Search code examples
parsingrustpattern-matchingmutability

Pattern Matching does not allow me to change values


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


Solution

  • 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)