You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: mod.rs
    path of file: ./repos/lalrpop/lalrpop/src/lr1/trace/reduce
    
    the code of the file until where you have to start completion: use crate::grammar::repr::*;
use crate::lr1::core::*;

use super::trace_graph::*;
use super::Tracer;

#[cfg(test)]
mod test;

impl<'trace, 'grammar> Tracer<'trace, 'grammar> {
    pub fn backtrace_reduce(
        mut self,
        item_state: StateIndex,
        item: Lr0Item<'grammar>,
    ) -> TraceGraph<'grammar> {
        self.trace_reduce_item(item_state, item);
        self.trace_graph
    }

    fn trace_reduce_item(&mut self, item_state: StateIndex, item: Lr0Item<'grammar>) {
        // We start out with an item
        //
        //     X = ...p (*) ...s
        //
        // which we can (eventually) reduce, though we may have to do
        // some epsilon reductions first if ...s is non-empty. We want
        // to trace back until we have (at least) one element of
        // context for the reduction.
        let nonterminal = &item.production.nonterminal; // X

        // Add an ed
    
    fn trace_reduce_item(&mut self, item_state: StateIndex, item: Lr0Item<'grammar>) {
        // We start out with an item
        //
        //     X = ...p (*) ...s
        //
        // which we can (eventually) reduce, though we may have to do
        // some epsilon reductions first if ...s is non-empty. We want
        // to trace back until we have (at least) one element of
        // context for the reduction.
        let nonterminal = &item.production.nonterminal; // X

        // Add an edge
        //
        //     [X] -{...p,_,...s}-> [X = ...p (*) ...s]
        //
        // because to reach that item we pushed `...p` from the start
        // of `X` and afterwards we expect to see `...s`.
        self.trace_graph
            .add_edge(nonterminal.clone(), item, item.symbol_sets());

        // Walk back to the set of states S where we had:
        //
        //     X = (*) ...p
        let pred_states = self.state_graph.trace_back(item_state, item.prefix());

        // Add in edges from [X] to all the places [X] can be consumed.
        for pred_state in pred_states {
            self.trace_reduce_from_state(pred_state, nonterminal);
        }
    }