fn try_backtrack<Dir: Direction>(
        &mut self,
        input: &Input,
        ip: &mut IP,
        pos: &mut Input::Position,
        _dir: Dir,
    ) -> bool {
        loop {
            // We always have a single Exhausted instruction backstopping our stack,
            // so we do not need to check for empty bts.
            debug_assert!(!self.bts.is_empty(), "Backtrack stack should not be empty");
            let bt = match self.bts.last_mut() {
                Some(bt) => bt,
                None => rs_unreachable!("BT stack should never be empty"),
            };
            match bt {
                BacktrackInsn::Exhausted => return false,

                BacktrackInsn::SetPosition {
                    ip: saved_ip,
                    pos: saved_pos,
                } => {
                    *ip = *saved_ip;
                    *pos = *saved_pos;
                    self.pop_backtrack();
                    return true;
                }
                BacktrackInsn::SetLoopData { id, data } => {
                    *self.s.loops.mat(*id as usize) = *data;
                    self.pop_backtrack();
                }
                BacktrackInsn::SetCaptureGroup { id, data } => {
                    *self.s.groups.mat(*id as usize) = *data;
                    self.pop_backtrack();
                }

                &mut BacktrackInsn::EnterNonGreedyLoop { ip: loop_ip, data } => {
                    // Must pop before we enter the loop.
                    self.pop_backtrack();
                    *ip = loop_ip + 1;
                    *pos = data.entry;
                    let loop_fields = match &self.re.insns.iat(loop_ip) {
                        Insn::EnterLoop(loop_fields) => loop_fields,
                        _ => rs_unreachable!("EnterNonGreedyLoop must point at a loop instruction"),
                    };
                    let loop_data = self.s.loops.mat(loop_fields.loop_id as usize);
                    *loop_data = data;
                    MatchAttempter::prepare_to_enter_loop(
                        &mut self.bts,
                        *pos,
                        loop_fields,
                        loop_data,
                    );
                    return true;
                }

                BacktrackInsn::GreedyLoop1Char {
                    continuation,
                    min,
                    max,
                } => {
                    // The match failed at the max location.
                    debug_assert!(
                        if Dir::FORWARD { max >= min } else { max <= min },
                        "max should be >= min (or <= if tracking backwards)"
                    );
                    // If min is equal to max, there is no more backtracking to be done;
                    // otherwise move opposite the direction of the cursor.
                    if *max == *min {
                        // We have backtracked this loop as far as possible.
                        self.bts.pop();
                        continue;
                    }
                    let newmax = if Dir::FORWARD {
                        input.next_left_pos(*max)
                    } else {
                        input.next_right_pos(*max)
                    };
                    if let Some(newmax) = newmax {
                        *pos = newmax;
                        *max = newmax;
                    } else {
                        rs_unreachable!("Should always be able to advance since min != max")
                    }
                    *ip = *continuation;
                    return true;
                }

                BacktrackInsn::NonGreedyLoop1Char {
                    continuation,
                    min,
                    max,
                } => {
                    // The match failed at the min location.
                    debug_assert!(
                        if Dir::FORWARD { max >= min } else { max <= min },
                        "max should be >= min (or <= if tracking backwards)"
                    );
                    if *max == *min {
                        // We have backtracked this loop as far as possible.
                        self.bts.pop();
                        continue;
                    }
                    // Move in the direction of the cursor.
                    let newmin = if Dir::FORWARD {
                        input.next_right_pos(*min)
                    } else {
                        input.next_left_pos(*min)
                    };
                    if let Some(newmin) = newmin {
                        *pos = newmin;
                        *min = newmin;
                    } else {
                        rs_unreachable!("Should always be able to advance since min != max")
                    }
                    *ip = *continuation;
                    return true;
                }
            }
        }
    }
/// Attempt to backtrack.
/// \return true if we backtracked, false if we exhaust the backtrack stack.
Attempt to backtrack.
\return true if we backtracked, false if we exhaust the backtrack stack.
Attempt to backtrack . \ return true if we backtracked false if we exhaust the backtrack stack .
fn try_backtrack<Dir: Direction>(
        &mut self,
        input: &Input,
        ip: &mut IP,
        pos: &mut Input::Position,
        _dir: Dir,
    ) -> bool {
        loop {
            // We always have a single Exhausted instruction backstopping our stack,
            // so we do not need to check for empty bts.
            debug_assert!(!self.bts.is_empty(), "Backtrack stack should not be empty");
            let bt = match self.bts.last_mut() {
                Some(bt) => bt,
                None => rs_unreachable!("BT stack should never be empty"),
            };
            match bt {
                BacktrackInsn::Exhausted => return false,
                BacktrackInsn::SetPosition {
                    ip: saved_ip,
                    pos: saved_pos,
                } => {
                    *ip = *saved_ip;
                    *pos = *saved_pos;
                    self.pop_backtrack();
                    return true;
                }
                BacktrackInsn::SetLoopData { id, data } => {
                    *self.s.loops.mat(*id as usize) = *data;
                    self.pop_backtrack();
                }
                BacktrackInsn::SetCaptureGroup { id, data } => {
                    *self.s.groups.mat(*id as usize) = *data;
                    self.pop_backtrack();
                }
                &mut BacktrackInsn::EnterNonGreedyLoop { ip: loop_ip, data } => {
                    // Must pop before we enter the loop.
                    self.pop_backtrack();
                    *ip = loop_ip + 1;
                    *pos = data.entry;
                    let loop_fields = match &self.re.insns.iat(loop_ip) {
                        Insn::EnterLoop(loop_fields) => loop_fields,
                        _ => rs_unreachable!("EnterNonGreedyLoop must point at a loop instruction"),
                    };
                    let loop_data = self.s.loops.mat(loop_fields.loop_id as usize);
                    *loop_data = data;
                    MatchAttempter::prepare_to_enter_loop(
                        &mut self.bts,
                        *pos,
                        loop_fields,
                        loop_data,
                    );
                    return true;
                }
                BacktrackInsn::GreedyLoop1Char {
                    continuation,
                    min,
                    max,
                } => {
                    // The match failed at the max location.
                    debug_assert!(
                        if Dir::FORWARD { max >= min } else { max <= min },
                        "max should be >= min (or <= if tracking backwards)"
                    );
                    // If min is equal to max, there is no more backtracking to be done;
                    // otherwise move opposite the direction of the cursor.
                    if *max == *min {
                        // We have backtracked this loop as far as possible.
                        self.bts.pop();
                        continue;
                    }
                    let newmax = if Dir::FORWARD {
                        input.next_left_pos(*max)
                    } else {
                        input.next_right_pos(*max)
                    };
                    if let Some(newmax) = newmax {
                        *pos = newmax;
                        *max = newmax;
                    } else {
                        rs_unreachable!("Should always be able to advance since min != max")
                    }
                    *ip = *continuation;
                    return true;
                }
                BacktrackInsn::NonGreedyLoop1Char {
                    continuation,
                    min,
                    max,
                } => {
                    // The match failed at the min location.
                    debug_assert!(
                        if Dir::FORWARD { max >= min } else { max <= min },
                        "max should be >= min (or <= if tracking backwards)"
                    );
                    if *max == *min {
                        // We have backtracked this loop as far as possible.
                        self.bts.pop();
                        continue;
                    }
                    // Move in the direction of the cursor.
                    let newmin = if Dir::FORWARD {
                        input.next_right_pos(*min)
                    } else {
                        input.next_left_pos(*min)
                    };
                    if let Some(newmin) = newmin {
                        *pos = newmin;
                        *min = newmin;
                    } else {
                        rs_unreachable!("Should always be able to advance since min != max")
                    }
                    *ip = *continuation;
                    return true;
                }
            }
        }
    }
fn try_backtrack < Dir : Direction > ( & mut self , input : & Input , ip : & mut IP , pos : & mut Input :: Position , _dir : Dir , ) -> bool { loop { // We always have a single Exhausted instruction backstopping our stack, // so we do not need to check for empty bts. debug_assert ! ( self bts is_empty ( ) " " ) ; let bt = match self . bts . last_mut ( ) { Some ( bt ) => bt , None => rs_unreachable ! ( " " ) , } ; match bt { BacktrackInsn :: Exhausted => return false , BacktrackInsn :: SetPosition { ip : saved_ip , pos : saved_pos , } => { * ip = * saved_ip ; * pos = * saved_pos ; self . pop_backtrack ( ) ; return true ; } BacktrackInsn :: SetLoopData { id , data } => { * self . s . loops . mat ( * id as usize ) = * data ; self . pop_backtrack ( ) ; } BacktrackInsn :: SetCaptureGroup { id , data } => { * self . s . groups . mat ( * id as usize ) = * data ; self . pop_backtrack ( ) ; } & mut BacktrackInsn :: EnterNonGreedyLoop { ip : loop_ip , data } => { // Must pop before we enter the loop. self . pop_backtrack ( ) ; * ip = loop_ip + 1 ; * pos = data . entry ; let loop_fields = match & self . re . insns . iat ( loop_ip ) { Insn :: EnterLoop ( loop_fields ) => loop_fields , _ => rs_unreachable ! ( " " ) , } ; let loop_data = self . s . loops . mat ( loop_fields . loop_id as usize ) ; * loop_data = data ; MatchAttempter :: prepare_to_enter_loop ( & mut self . bts , * pos , loop_fields , loop_data , ) ; return true ; } BacktrackInsn :: GreedyLoop1Char { continuation , min , max , } => { // The match failed at the max location. debug_assert ! ( if Dir FORWARD { max min } else { max min } " " ) ; // If min is equal to max, there is no more backtracking to be done; // otherwise move opposite the direction of the cursor. if * max == * min { // We have backtracked this loop as far as possible. self . bts . pop ( ) ; continue ; } let newmax = if Dir :: FORWARD { input . next_left_pos ( * max ) } else { input . next_right_pos ( * max ) } ; if let Some ( newmax ) = newmax { * pos = newmax ; * max = newmax ; } else { rs_unreachable ! ( " " ) } * ip = * continuation ; return true ; } BacktrackInsn :: NonGreedyLoop1Char { continuation , min , max , } => { // The match failed at the min location. debug_assert ! ( if Dir FORWARD { max min } else { max min } " " ) ; if * max == * min { // We have backtracked this loop as far as possible. self . bts . pop ( ) ; continue ; } // Move in the direction of the cursor. let newmin = if Dir :: FORWARD { input . next_right_pos ( * min ) } else { input . next_left_pos ( * min ) } ; if let Some ( newmin ) = newmin { * pos = newmin ; * min = newmin ; } else { rs_unreachable ! ( " " ) } * ip = * continuation ; return true ; } } } }
Attempt to backtrack.
Attempt to backtrack .
&mut self
input
&Input
ip
&mut IP
pos
&mut Input::Position
_dir
Dir