Home > OS >  Pattern Matching does not allow me to change values
Pattern Matching does not allow me to change values

Time:10-20

so I am currently working on a new programming language tr-lang

and I am currently in the process of writing the parser of the language

this piece of code is where the bug lies

BlockToken::İse(bip) => {
    let ise = &mut parsed[bip]; // Access method 1
    match ise.typ {
        TokenType::İse ( mut yoksa ) => {
            yoksa = Some(ip);
        },
        TokenType::Yoksa ( mut tp ) => {
            tp = Some(ip);
        },
        _ => unreachable!(),
    }
    ip   1
},
BlockToken::İken(bip) => {
    let iken = parsed.get_mut(bip).unwrap(); // Trying other access methods
        match iken.typ {
            TokenType::İken ( mut yoksa ) => {
                yoksa = Some(ip   1);
        },
        _ => unreachable!(),
    }
    bip
    },
    _ => unimplemented!(),
};

and this is part of the code that parses and produces an executable program

and it gives a few warnings but i think the problem lies in these ones:

warning: variable `yoksa` is assigned to, but never used
   --> src/parser/parser.rs:121:54
    |
121 | ...                   TokenType::İse ( mut yoksa ) => {
    |                                            ^^^^^
    |
    = note: consider using `_yoksa` instead

warning: value assigned to `yoksa` is never read
   --> src/parser/parser.rs:122:37
    |
122 | ...                   yoksa = Some(ip);
    |                       ^^^^^
    |
    = help: maybe it is overwritten before being read?

warning: variable `tp` is assigned to, but never used
   --> src/parser/parser.rs:124:56
    |
124 | ...                   TokenType::Yoksa ( mut tp ) => {
    |                                              ^^
    |
    = note: consider using `_tp` instead

warning: value assigned to `tp` is never read
   --> src/parser/parser.rs:125:37
    |
125 | ...                   tp = Some(ip);
    |                       ^^
    |
    = help: maybe it is overwritten before being read?

warning: variable `yoksa` is assigned to, but never used
   --> src/parser/parser.rs:134:55
    |
134 | ...                   TokenType::İken ( mut yoksa ) => {
    |                                             ^^^^^
    |
    = note: consider using `_yoksa` instead

warning: value assigned to `yoksa` is never read
   --> src/parser/parser.rs:135:37
    |
135 | ...                   yoksa = Some(ip   1);
    |                       ^^^^^
    |
    = help: maybe it is overwritten before being read?

as you can see for some reason even though i pattern-match like usual when i try to set the value to something else it treats the variables as different

and instead of changing the value of yoksa/tp the end result just does not change anything

i tried changing the way i access ise/iken however it didn't change anything i also tried using if let instead of match

it doesn't change the value of ise.typ.yoksa or ise.typ.tp

for extra info BlockToken is this enum

enum BlockToken {
    İse(usize),
    İken(usize),
    İkiNoktaNokta(usize),
}

Token is this struct

struct Token {
    pub typ:  TokenType,
    pub line: usize,
    pub col:  usize,
}

what i want from here is the ability to change the contents of the enum structs İse, İken and Yoksa

it can be unsafe although a safe method is preferred

CodePudding user response:

Use Option::replace to fit the new value into the mutable option:

yoksa.replace(ip   1);

Also you probably want a mutable reference:

TokenType::İken(ref mut yoksa)

CodePudding user response:

I think you need to match on a mutable reference when matching otherwise you are just creating a local variable and mutating that.

For example this code:

#[derive(Debug)]      
enum Blah {      
    A(u64),      
}      
      
mod test {      
    use crate::refmatch::Blah;      
      
    #[test]      
    fn test_match() {      
        let mut a = Blah::A(23);      
        println!("{:?}", a);                                   
                                                               
        match a {                                              
            Blah::A(ref mut x) => *x = 5,                      
        }                                                      
        println!("{:?}", a);                                   
    }                                                          
}

will output:

running 1 test
A(23)
A(5)

If you run it with cargo test -- --nocapture.

  • Related