fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
-> Option<(Span, Token)> where I: Iterator<Item=&'a TokenTree> {
    use print::pprust::token_to_string;

    let mut last = None;

    // 2. For each token T in M:
    let mut tokens = matcher.peekable();
    while let Some(token) = tokens.next() {
        last = match *token {
            TtToken(sp, MatchNt(ref name, ref frag_spec, _, _)) => {
                // ii. If T is a simple NT, look ahead to the next token T' in
                // M.
                let next_token = match tokens.peek() {
                    // If T' closes a complex NT, replace T' with F
                    Some(&&TtToken(_, CloseDelim(_))) => follow.clone(),
                    Some(&&TtToken(_, ref tok)) => tok.clone(),
                    Some(&&TtSequence(sp, _)) => {
                        cx.span_err(sp,
                                    &format!("`${0}:{1}` is followed by a \
                                              sequence repetition, which is not \
                                              allowed for `{1}` fragments",
                                             name.as_str(), frag_spec.as_str())
                                        );
                        Eof
                    },
                    // die next iteration
                    Some(&&TtDelimited(_, ref delim)) => delim.close_token(),
                    // else, we're at the end of the macro or sequence
                    None => follow.clone()
                };

                let tok = if let TtToken(_, ref tok) = *token { tok } else { unreachable!() };
                // If T' is in the set FOLLOW(NT), continue. Else, reject.
                match (&next_token, is_in_follow(cx, &next_token, frag_spec.as_str())) {
                    (_, Err(msg)) => {
                        cx.span_err(sp, &msg);
                        continue
                    }
                    (&Eof, _) => return Some((sp, tok.clone())),
                    (_, Ok(true)) => continue,
                    (next, Ok(false)) => {
                        cx.span_err(sp, &format!("`${0}:{1}` is followed by `{2}`, which \
                                                  is not allowed for `{1}` fragments",
                                                 name.as_str(), frag_spec.as_str(),
                                                 token_to_string(next)));
                        continue
                    },
                }
            },
            TtSequence(sp, ref seq) => {
                // iii. Else, T is a complex NT.
                match seq.separator {
                    // If T has the form $(...)U+ or $(...)U* for some token U,
                    // run the algorithm on the contents with F set to U. If it
                    // accepts, continue, else, reject.
                    Some(ref u) => {
                        let last = check_matcher(cx, seq.tts.iter(), u);
                        match last {
                            // Since the delimiter isn't required after the last
                            // repetition, make sure that the *next* token is
                            // sane. This doesn't actually compute the FIRST of
                            // the rest of the matcher yet, it only considers
                            // single tokens and simple NTs. This is imprecise,
                            // but conservatively correct.
                            Some((span, tok)) => {
                                let fol = match tokens.peek() {
                                    Some(&&TtToken(_, ref tok)) => tok.clone(),
                                    Some(&&TtDelimited(_, ref delim)) => delim.close_token(),
                                    Some(_) => {
                                        cx.span_err(sp, "sequence repetition followed by \
                                                another sequence repetition, which is not allowed");
                                        Eof
                                    },
                                    None => Eof
                                };
                                check_matcher(cx, Some(&TtToken(span, tok.clone())).into_iter(),
                                              &fol)
                            },
                            None => last,
                        }
                    },
                    // If T has the form $(...)+ or $(...)*, run the algorithm
                    // on the contents with F set to the token following the
                    // sequence. If it accepts, continue, else, reject.
                    None => {
                        let fol = match tokens.peek() {
                            Some(&&TtToken(_, ref tok)) => tok.clone(),
                            Some(&&TtDelimited(_, ref delim)) => delim.close_token(),
                            Some(_) => {
                                cx.span_err(sp, "sequence repetition followed by another \
                                             sequence repetition, which is not allowed");
                                Eof
                            },
                            None => Eof
                        };
                        check_matcher(cx, seq.tts.iter(), &fol)
                    }
                }
            },
            TtToken(..) => {
                // i. If T is not an NT, continue.
                continue
            },
            TtDelimited(_, ref tts) => {
                // if we don't pass in that close delimiter, we'll incorrectly consider the matcher
                // `{ $foo:ty }` as having a follow that isn't `RBrace`
                check_matcher(cx, tts.tts.iter(), &tts.close_token())
            }
        }
    }
    last
}
// returns the last token that was checked, for TtSequence. this gets used later on.
returns the last token that was checked, for TtSequence. this gets used later on.
returns the last token that was checked for TtSequence . this gets used later on .
fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
-> Option<(Span, Token)> where I: Iterator<Item=&'a TokenTree> {
    use print::pprust::token_to_string;
    let mut last = None;
    // 2. For each token T in M:
    let mut tokens = matcher.peekable();
    while let Some(token) = tokens.next() {
        last = match *token {
            TtToken(sp, MatchNt(ref name, ref frag_spec, _, _)) => {
                // ii. If T is a simple NT, look ahead to the next token T' in
                // M.
                let next_token = match tokens.peek() {
                    // If T' closes a complex NT, replace T' with F
                    Some(&&TtToken(_, CloseDelim(_))) => follow.clone(),
                    Some(&&TtToken(_, ref tok)) => tok.clone(),
                    Some(&&TtSequence(sp, _)) => {
                        cx.span_err(sp,
                                    &format!("`${0}:{1}` is followed by a \
                                              sequence repetition, which is not \
                                              allowed for `{1}` fragments",
                                             name.as_str(), frag_spec.as_str())
                                        );
                        Eof
                    },
                    // die next iteration
                    Some(&&TtDelimited(_, ref delim)) => delim.close_token(),
                    // else, we're at the end of the macro or sequence
                    None => follow.clone()
                };
                let tok = if let TtToken(_, ref tok) = *token { tok } else { unreachable!() };
                // If T' is in the set FOLLOW(NT), continue. Else, reject.
                match (&next_token, is_in_follow(cx, &next_token, frag_spec.as_str())) {
                    (_, Err(msg)) => {
                        cx.span_err(sp, &msg);
                        continue
                    }
                    (&Eof, _) => return Some((sp, tok.clone())),
                    (_, Ok(true)) => continue,
                    (next, Ok(false)) => {
                        cx.span_err(sp, &format!("`${0}:{1}` is followed by `{2}`, which \
                                                  is not allowed for `{1}` fragments",
                                                 name.as_str(), frag_spec.as_str(),
                                                 token_to_string(next)));
                        continue
                    },
                }
            },
            TtSequence(sp, ref seq) => {
                // iii. Else, T is a complex NT.
                match seq.separator {
                    // If T has the form $(...)U+ or $(...)U* for some token U,
                    // run the algorithm on the contents with F set to U. If it
                    // accepts, continue, else, reject.
                    Some(ref u) => {
                        let last = check_matcher(cx, seq.tts.iter(), u);
                        match last {
                            // Since the delimiter isn't required after the last
                            // repetition, make sure that the *next* token is
                            // sane. This doesn't actually compute the FIRST of
                            // the rest of the matcher yet, it only considers
                            // single tokens and simple NTs. This is imprecise,
                            // but conservatively correct.
                            Some((span, tok)) => {
                                let fol = match tokens.peek() {
                                    Some(&&TtToken(_, ref tok)) => tok.clone(),
                                    Some(&&TtDelimited(_, ref delim)) => delim.close_token(),
                                    Some(_) => {
                                        cx.span_err(sp, "sequence repetition followed by \
                                                another sequence repetition, which is not allowed");
                                        Eof
                                    },
                                    None => Eof
                                };
                                check_matcher(cx, Some(&TtToken(span, tok.clone())).into_iter(),
                                              &fol)
                            },
                            None => last,
                        }
                    },
                    // If T has the form $(...)+ or $(...)*, run the algorithm
                    // on the contents with F set to the token following the
                    // sequence. If it accepts, continue, else, reject.
                    None => {
                        let fol = match tokens.peek() {
                            Some(&&TtToken(_, ref tok)) => tok.clone(),
                            Some(&&TtDelimited(_, ref delim)) => delim.close_token(),
                            Some(_) => {
                                cx.span_err(sp, "sequence repetition followed by another \
                                             sequence repetition, which is not allowed");
                                Eof
                            },
                            None => Eof
                        };
                        check_matcher(cx, seq.tts.iter(), &fol)
                    }
                }
            },
            TtToken(..) => {
                // i. If T is not an NT, continue.
                continue
            },
            TtDelimited(_, ref tts) => {
                // if we don't pass in that close delimiter, we'll incorrectly consider the matcher
                // `{ $foo:ty }` as having a follow that isn't `RBrace`
                check_matcher(cx, tts.tts.iter(), &tts.close_token())
            }
        }
    }
    last
}
fn check_matcher < ' a , I > ( cx : & mut ExtCtxt , matcher : I , follow : & Token ) -> Option < ( Span , Token ) > where I : Iterator < Item = & ' a TokenTree > { use print :: pprust :: token_to_string ; let mut last = None ; // 2. For each token T in M: let mut tokens = matcher . peekable ( ) ; while let Some ( token ) = tokens . next ( ) { last = match * token { TtToken ( sp , MatchNt ( ref name , ref frag_spec , _ , _ ) ) => { // ii. If T is a simple NT, look ahead to the next token T' in // M. let next_token = match tokens . peek ( ) { // If T' closes a complex NT, replace T' with F Some ( & & TtToken ( _ , CloseDelim ( _ ) ) ) => follow . clone ( ) , Some ( & & TtToken ( _ , ref tok ) ) => tok . clone ( ) , Some ( & & TtSequence ( sp , _ ) ) => { cx . span_err ( sp , & format ! ( " \
 \
 " name as_str ( ) frag_spec as_str ( ) ) ) ; Eof } , // die next iteration Some ( & & TtDelimited ( _ , ref delim ) ) => delim . close_token ( ) , // else, we're at the end of the macro or sequence None => follow . clone ( ) } ; let tok = if let TtToken ( _ , ref tok ) = * token { tok } else { unreachable ! ( ) } ; // If T' is in the set FOLLOW(NT), continue. Else, reject. match ( & next_token , is_in_follow ( cx , & next_token , frag_spec . as_str ( ) ) ) { ( _ , Err ( msg ) ) => { cx . span_err ( sp , & msg ) ; continue } ( & Eof , _ ) => return Some ( ( sp , tok . clone ( ) ) ) , ( _ , Ok ( true ) ) => continue , ( next , Ok ( false ) ) => { cx . span_err ( sp , & format ! ( " \
 " name as_str ( ) frag_spec as_str ( ) token_to_string ( next ) ) ) ; continue } , } } , TtSequence ( sp , ref seq ) => { // iii. Else, T is a complex NT. match seq . separator { // If T has the form $(...)U+ or $(...)U* for some token U, // run the algorithm on the contents with F set to U. If it // accepts, continue, else, reject. Some ( ref u ) => { let last = check_matcher ( cx , seq . tts . iter ( ) , u ) ; match last { // Since the delimiter isn't required after the last // repetition, make sure that the *next* token is // sane. This doesn't actually compute the FIRST of // the rest of the matcher yet, it only considers // single tokens and simple NTs. This is imprecise, // but conservatively correct. Some ( ( span , tok ) ) => { let fol = match tokens . peek ( ) { Some ( & & TtToken ( _ , ref tok ) ) => tok . clone ( ) , Some ( & & TtDelimited ( _ , ref delim ) ) => delim . close_token ( ) , Some ( _ ) => { cx . span_err ( sp , " \
 " ) ; Eof } , None => Eof } ; check_matcher ( cx , Some ( & TtToken ( span , tok . clone ( ) ) ) . into_iter ( ) , & fol ) } , None => last , } } , // If T has the form $(...)+ or $(...)*, run the algorithm // on the contents with F set to the token following the // sequence. If it accepts, continue, else, reject. None => { let fol = match tokens . peek ( ) { Some ( & & TtToken ( _ , ref tok ) ) => tok . clone ( ) , Some ( & & TtDelimited ( _ , ref delim ) ) => delim . close_token ( ) , Some ( _ ) => { cx . span_err ( sp , " \
 " ) ; Eof } , None => Eof } ; check_matcher ( cx , seq . tts . iter ( ) , & fol ) } } } , TtToken ( .. ) => { // i. If T is not an NT, continue. continue } , TtDelimited ( _ , ref tts ) => { // if we don't pass in that close delimiter, we'll incorrectly consider the matcher // `{ $foo:ty }` as having a follow that isn't `RBrace` check_matcher ( cx , tts . tts . iter ( ) , & tts . close_token ( ) ) } } } last }
returns the last token that was checked, for TtSequence.
returns the last token that was checked for TtSequence .
cx
&mut ExtCtxt
matcher
I
follow
&Token