fn expand_bang_invoc(&mut self, invoc: Invocation, ext: Rc<SyntaxExtension>) -> Expansion {
        let (mark, kind) = (invoc.expansion_data.mark, invoc.expansion_kind);
        let (mac, ident, span) = match invoc.kind {
            InvocationKind::Bang { mac, ident, span } => (mac, ident, span),
            _ => unreachable!(),
        };
        let Mac_ { path, tts, .. } = mac.node;

        let extname = path.segments.last().unwrap().identifier.name;
        let ident = ident.unwrap_or(keywords::Invalid.ident());
        let marked_tts = mark_tts(&tts, mark);
        let opt_expanded = match *ext {
            NormalTT(ref expandfun, exp_span, allow_internal_unstable) => {
                if ident.name != keywords::Invalid.name() {
                    let msg =
                        format!("macro {}! expects no ident argument, given '{}'", extname, ident);
                    self.cx.span_err(path.span, &msg);
                    return kind.dummy(span);
                }

                self.cx.bt_push(ExpnInfo {
                    call_site: span,
                    callee: NameAndSpan {
                        format: MacroBang(extname),
                        span: exp_span,
                        allow_internal_unstable: allow_internal_unstable,
                    },
                });

                kind.make_from(expandfun.expand(self.cx, span, &marked_tts))
            }

            IdentTT(ref expander, tt_span, allow_internal_unstable) => {
                if ident.name == keywords::Invalid.name() {
                    self.cx.span_err(path.span,
                                    &format!("macro {}! expects an ident argument", extname));
                    return kind.dummy(span);
                };

                self.cx.bt_push(ExpnInfo {
                    call_site: span,
                    callee: NameAndSpan {
                        format: MacroBang(extname),
                        span: tt_span,
                        allow_internal_unstable: allow_internal_unstable,
                    }
                });

                kind.make_from(expander.expand(self.cx, span, ident, marked_tts))
            }

            MultiDecorator(..) | MultiModifier(..) | SyntaxExtension::AttrProcMacro(..) => {
                self.cx.span_err(path.span,
                                 &format!("`{}` can only be used in attributes", extname));
                return kind.dummy(span);
            }

            SyntaxExtension::ProcMacroDerive(..) | SyntaxExtension::BuiltinDerive(..) => {
                self.cx.span_err(path.span, &format!("`{}` is a derive mode", extname));
                return kind.dummy(span);
            }

            SyntaxExtension::ProcMacro(ref expandfun) => {
                if ident.name != keywords::Invalid.name() {
                    let msg =
                        format!("macro {}! expects no ident argument, given '{}'", extname, ident);
                    self.cx.span_err(path.span, &msg);
                    return kind.dummy(span);
                }

                self.cx.bt_push(ExpnInfo {
                    call_site: span,
                    callee: NameAndSpan {
                        format: MacroBang(extname),
                        // FIXME procedural macros do not have proper span info
                        // yet, when they do, we should use it here.
                        span: None,
                        // FIXME probably want to follow macro_rules macros here.
                        allow_internal_unstable: false,
                    },
                });

                let toks = marked_tts.into_iter().collect();
                let tok_result = expandfun.expand(self.cx, span, toks);
                Some(self.parse_expansion(tok_result, kind, extname, span))
            }
        };

        let expanded = if let Some(expanded) = opt_expanded {
            expanded
        } else {
            let msg = format!("non-{kind} macro in {kind} position: {name}",
                              name = path.segments[0].identifier.name, kind = kind.name());
            self.cx.span_err(path.span, &msg);
            return kind.dummy(span);
        };

        expanded.fold_with(&mut Marker {
            mark: mark,
            expn_id: Some(self.cx.backtrace()),
        })
    }
/// Expand a macro invocation. Returns the result of expansion.
Expand a macro invocation. Returns the result of expansion.
Expand a macro invocation . Returns the result of expansion .
fn expand_bang_invoc(&mut self, invoc: Invocation, ext: Rc<SyntaxExtension>) -> Expansion {
        let (mark, kind) = (invoc.expansion_data.mark, invoc.expansion_kind);
        let (mac, ident, span) = match invoc.kind {
            InvocationKind::Bang { mac, ident, span } => (mac, ident, span),
            _ => unreachable!(),
        };
        let Mac_ { path, tts, .. } = mac.node;
        let extname = path.segments.last().unwrap().identifier.name;
        let ident = ident.unwrap_or(keywords::Invalid.ident());
        let marked_tts = mark_tts(&tts, mark);
        let opt_expanded = match *ext {
            NormalTT(ref expandfun, exp_span, allow_internal_unstable) => {
                if ident.name != keywords::Invalid.name() {
                    let msg =
                        format!("macro {}! expects no ident argument, given '{}'", extname, ident);
                    self.cx.span_err(path.span, &msg);
                    return kind.dummy(span);
                }
                self.cx.bt_push(ExpnInfo {
                    call_site: span,
                    callee: NameAndSpan {
                        format: MacroBang(extname),
                        span: exp_span,
                        allow_internal_unstable: allow_internal_unstable,
                    },
                });
                kind.make_from(expandfun.expand(self.cx, span, &marked_tts))
            }
            IdentTT(ref expander, tt_span, allow_internal_unstable) => {
                if ident.name == keywords::Invalid.name() {
                    self.cx.span_err(path.span,
                                    &format!("macro {}! expects an ident argument", extname));
                    return kind.dummy(span);
                };
                self.cx.bt_push(ExpnInfo {
                    call_site: span,
                    callee: NameAndSpan {
                        format: MacroBang(extname),
                        span: tt_span,
                        allow_internal_unstable: allow_internal_unstable,
                    }
                });
                kind.make_from(expander.expand(self.cx, span, ident, marked_tts))
            }
            MultiDecorator(..) | MultiModifier(..) | SyntaxExtension::AttrProcMacro(..) => {
                self.cx.span_err(path.span,
                                 &format!("`{}` can only be used in attributes", extname));
                return kind.dummy(span);
            }
            SyntaxExtension::ProcMacroDerive(..) | SyntaxExtension::BuiltinDerive(..) => {
                self.cx.span_err(path.span, &format!("`{}` is a derive mode", extname));
                return kind.dummy(span);
            }
            SyntaxExtension::ProcMacro(ref expandfun) => {
                if ident.name != keywords::Invalid.name() {
                    let msg =
                        format!("macro {}! expects no ident argument, given '{}'", extname, ident);
                    self.cx.span_err(path.span, &msg);
                    return kind.dummy(span);
                }
                self.cx.bt_push(ExpnInfo {
                    call_site: span,
                    callee: NameAndSpan {
                        format: MacroBang(extname),
                        // FIXME procedural macros do not have proper span info
                        // yet, when they do, we should use it here.
                        span: None,
                        // FIXME probably want to follow macro_rules macros here.
                        allow_internal_unstable: false,
                    },
                });
                let toks = marked_tts.into_iter().collect();
                let tok_result = expandfun.expand(self.cx, span, toks);
                Some(self.parse_expansion(tok_result, kind, extname, span))
            }
        };
        let expanded = if let Some(expanded) = opt_expanded {
            expanded
        } else {
            let msg = format!("non-{kind} macro in {kind} position: {name}",
                              name = path.segments[0].identifier.name, kind = kind.name());
            self.cx.span_err(path.span, &msg);
            return kind.dummy(span);
        };
        expanded.fold_with(&mut Marker {
            mark: mark,
            expn_id: Some(self.cx.backtrace()),
        })
    }
fn expand_bang_invoc ( & mut self , invoc : Invocation , ext : Rc < SyntaxExtension > ) -> Expansion { let ( mark , kind ) = ( invoc . expansion_data . mark , invoc . expansion_kind ) ; let ( mac , ident , span ) = match invoc . kind { InvocationKind :: Bang { mac , ident , span } => ( mac , ident , span ) , _ => unreachable ! ( ) , } ; let Mac_ { path , tts , .. } = mac . node ; let extname = path . segments . last ( ) . unwrap ( ) . identifier . name ; let ident = ident . unwrap_or ( keywords :: Invalid . ident ( ) ) ; let marked_tts = mark_tts ( & tts , mark ) ; let opt_expanded = match * ext { NormalTT ( ref expandfun , exp_span , allow_internal_unstable ) => { if ident . name != keywords :: Invalid . name ( ) { let msg = format ! ( " " extname ident ) ; self . cx . span_err ( path . span , & msg ) ; return kind . dummy ( span ) ; } self . cx . bt_push ( ExpnInfo { call_site : span , callee : NameAndSpan { format : MacroBang ( extname ) , span : exp_span , allow_internal_unstable : allow_internal_unstable , } , } ) ; kind . make_from ( expandfun . expand ( self . cx , span , & marked_tts ) ) } IdentTT ( ref expander , tt_span , allow_internal_unstable ) => { if ident . name == keywords :: Invalid . name ( ) { self . cx . span_err ( path . span , & format ! ( " " extname ) ) ; return kind . dummy ( span ) ; } ; self . cx . bt_push ( ExpnInfo { call_site : span , callee : NameAndSpan { format : MacroBang ( extname ) , span : tt_span , allow_internal_unstable : allow_internal_unstable , } } ) ; kind . make_from ( expander . expand ( self . cx , span , ident , marked_tts ) ) } MultiDecorator ( .. ) | MultiModifier ( .. ) | SyntaxExtension :: AttrProcMacro ( .. ) => { self . cx . span_err ( path . span , & format ! ( " " extname ) ) ; return kind . dummy ( span ) ; } SyntaxExtension :: ProcMacroDerive ( .. ) | SyntaxExtension :: BuiltinDerive ( .. ) => { self . cx . span_err ( path . span , & format ! ( " " extname ) ) ; return kind . dummy ( span ) ; } SyntaxExtension :: ProcMacro ( ref expandfun ) => { if ident . name != keywords :: Invalid . name ( ) { let msg = format ! ( " " extname ident ) ; self . cx . span_err ( path . span , & msg ) ; return kind . dummy ( span ) ; } self . cx . bt_push ( ExpnInfo { call_site : span , callee : NameAndSpan { format : MacroBang ( extname ) , // FIXME procedural macros do not have proper span info // yet, when they do, we should use it here. span : None , // FIXME probably want to follow macro_rules macros here. allow_internal_unstable : false , } , } ) ; let toks = marked_tts . into_iter ( ) . collect ( ) ; let tok_result = expandfun . expand ( self . cx , span , toks ) ; Some ( self . parse_expansion ( tok_result , kind , extname , span ) ) } } ; let expanded = if let Some ( expanded ) = opt_expanded { expanded } else { let msg = format ! ( " " name path segments [ 0 ] identifier name kind kind name ( ) ) ; self . cx . span_err ( path . span , & msg ) ; return kind . dummy ( span ) ; } ; expanded . fold_with ( & mut Marker { mark : mark , expn_id : Some ( self . cx . backtrace ( ) ) , } ) }
Expand a macro invocation.
Expand a macro invocation .
&mut self
invoc
Invocation
ext
Rc<SyntaxExtension>
&mut self
invoc
Invocation
ext
Rc<SyntaxExtension>