pub fn expand_item_mac(it: P<ast::Item>,
                       fld: &mut MacroExpander) -> SmallVector<P<ast::Item>> {
    let (extname, path_span, tts) = match it.node {
        ItemMac(codemap::Spanned {
            node: MacInvocTT(ref pth, ref tts, _),
            ..
        }) => {
            (pth.segments[0].identifier.name, pth.span, (*tts).clone())
        }
        _ => fld.cx.span_bug(it.span, "invalid item macro invocation")
    };

    let fm = fresh_mark();
    let items = {
        let expanded = match fld.cx.syntax_env.find(&extname) {
            None => {
                fld.cx.span_err(path_span,
                                &format!("macro undefined: '{}!'",
                                        extname));
                // let compilation continue
                return SmallVector::zero();
            }

            Some(rc) => match *rc {
                NormalTT(ref expander, span, allow_internal_unstable) => {
                    if it.ident.name != parse::token::special_idents::invalid.name {
                        fld.cx
                            .span_err(path_span,
                                      &format!("macro {}! expects no ident argument, given '{}'",
                                               extname,
                                               it.ident));
                        return SmallVector::zero();
                    }
                    fld.cx.bt_push(ExpnInfo {
                        call_site: it.span,
                        callee: NameAndSpan {
                            format: MacroBang(extname),
                            span: span,
                            allow_internal_unstable: allow_internal_unstable,
                        }
                    });
                    // mark before expansion:
                    let marked_before = mark_tts(&tts[..], fm);
                    expander.expand(fld.cx, it.span, &marked_before[..])
                }
                IdentTT(ref expander, span, allow_internal_unstable) => {
                    if it.ident.name == parse::token::special_idents::invalid.name {
                        fld.cx.span_err(path_span,
                                        &format!("macro {}! expects an ident argument",
                                                extname));
                        return SmallVector::zero();
                    }
                    fld.cx.bt_push(ExpnInfo {
                        call_site: it.span,
                        callee: NameAndSpan {
                            format: MacroBang(extname),
                            span: span,
                            allow_internal_unstable: allow_internal_unstable,
                        }
                    });
                    // mark before expansion:
                    let marked_tts = mark_tts(&tts[..], fm);
                    expander.expand(fld.cx, it.span, it.ident, marked_tts)
                }
                MacroRulesTT => {
                    if it.ident.name == parse::token::special_idents::invalid.name {
                        fld.cx.span_err(path_span,
                                        &format!("macro_rules! expects an ident argument")
                                        );
                        return SmallVector::zero();
                    }

                    fld.cx.bt_push(ExpnInfo {
                        call_site: it.span,
                        callee: NameAndSpan {
                            format: MacroBang(extname),
                            span: None,
                            // `macro_rules!` doesn't directly allow
                            // unstable (this is orthogonal to whether
                            // the macro it creates allows it)
                            allow_internal_unstable: false,
                        }
                    });
                    // DON'T mark before expansion.

                    let allow_internal_unstable = attr::contains_name(&it.attrs,
                                                                      "allow_internal_unstable");

                    // ensure any #[allow_internal_unstable]s are
                    // detected (including nested macro definitions
                    // etc.)
                    if allow_internal_unstable && !fld.cx.ecfg.enable_allow_internal_unstable() {
                        feature_gate::emit_feature_err(
                            &fld.cx.parse_sess.span_diagnostic,
                            "allow_internal_unstable",
                            it.span,
                            feature_gate::EXPLAIN_ALLOW_INTERNAL_UNSTABLE)
                    }

                    let def = ast::MacroDef {
                        ident: it.ident,
                        attrs: it.attrs.clone(),
                        id: ast::DUMMY_NODE_ID,
                        span: it.span,
                        imported_from: None,
                        export: attr::contains_name(&it.attrs, "macro_export"),
                        use_locally: true,
                        allow_internal_unstable: allow_internal_unstable,
                        body: tts,
                    };
                    fld.cx.insert_macro(def);

                    // macro_rules! has a side effect but expands to nothing.
                    fld.cx.bt_pop();
                    return SmallVector::zero();
                }
                _ => {
                    fld.cx.span_err(it.span,
                                    &format!("{}! is not legal in item position",
                                            extname));
                    return SmallVector::zero();
                }
            }
        };

        expanded.make_items()
    };

    let items = match items {
        Some(items) => {
            items.into_iter()
                .map(|i| mark_item(i, fm))
                .flat_map(|i| fld.fold_item(i).into_iter())
                .collect()
        }
        None => {
            fld.cx.span_err(path_span,
                            &format!("non-item macro in item position: {}",
                                    extname));
            return SmallVector::zero();
        }
    };

    fld.cx.bt_pop();
    items
}
// Support for item-position macro invocations, exactly the same
// logic as for expression-position macro invocations.
Support for item-position macro invocations, exactly the same
logic as for expression-position macro invocations.
Support for item - position macro invocations exactly the same logic as for expression - position macro invocations .
pub fn expand_item_mac(it: P<ast::Item>,
                       fld: &mut MacroExpander) -> SmallVector<P<ast::Item>> {
    let (extname, path_span, tts) = match it.node {
        ItemMac(codemap::Spanned {
            node: MacInvocTT(ref pth, ref tts, _),
            ..
        }) => {
            (pth.segments[0].identifier.name, pth.span, (*tts).clone())
        }
        _ => fld.cx.span_bug(it.span, "invalid item macro invocation")
    };
    let fm = fresh_mark();
    let items = {
        let expanded = match fld.cx.syntax_env.find(&extname) {
            None => {
                fld.cx.span_err(path_span,
                                &format!("macro undefined: '{}!'",
                                        extname));
                // let compilation continue
                return SmallVector::zero();
            }
            Some(rc) => match *rc {
                NormalTT(ref expander, span, allow_internal_unstable) => {
                    if it.ident.name != parse::token::special_idents::invalid.name {
                        fld.cx
                            .span_err(path_span,
                                      &format!("macro {}! expects no ident argument, given '{}'",
                                               extname,
                                               it.ident));
                        return SmallVector::zero();
                    }
                    fld.cx.bt_push(ExpnInfo {
                        call_site: it.span,
                        callee: NameAndSpan {
                            format: MacroBang(extname),
                            span: span,
                            allow_internal_unstable: allow_internal_unstable,
                        }
                    });
                    // mark before expansion:
                    let marked_before = mark_tts(&tts[..], fm);
                    expander.expand(fld.cx, it.span, &marked_before[..])
                }
                IdentTT(ref expander, span, allow_internal_unstable) => {
                    if it.ident.name == parse::token::special_idents::invalid.name {
                        fld.cx.span_err(path_span,
                                        &format!("macro {}! expects an ident argument",
                                                extname));
                        return SmallVector::zero();
                    }
                    fld.cx.bt_push(ExpnInfo {
                        call_site: it.span,
                        callee: NameAndSpan {
                            format: MacroBang(extname),
                            span: span,
                            allow_internal_unstable: allow_internal_unstable,
                        }
                    });
                    // mark before expansion:
                    let marked_tts = mark_tts(&tts[..], fm);
                    expander.expand(fld.cx, it.span, it.ident, marked_tts)
                }
                MacroRulesTT => {
                    if it.ident.name == parse::token::special_idents::invalid.name {
                        fld.cx.span_err(path_span,
                                        &format!("macro_rules! expects an ident argument")
                                        );
                        return SmallVector::zero();
                    }
                    fld.cx.bt_push(ExpnInfo {
                        call_site: it.span,
                        callee: NameAndSpan {
                            format: MacroBang(extname),
                            span: None,
                            // `macro_rules!` doesn't directly allow
                            // unstable (this is orthogonal to whether
                            // the macro it creates allows it)
                            allow_internal_unstable: false,
                        }
                    });
                    // DON'T mark before expansion.
                    let allow_internal_unstable = attr::contains_name(&it.attrs,
                                                                      "allow_internal_unstable");
                    // ensure any #[allow_internal_unstable]s are
                    // detected (including nested macro definitions
                    // etc.)
                    if allow_internal_unstable && !fld.cx.ecfg.enable_allow_internal_unstable() {
                        feature_gate::emit_feature_err(
                            &fld.cx.parse_sess.span_diagnostic,
                            "allow_internal_unstable",
                            it.span,
                            feature_gate::EXPLAIN_ALLOW_INTERNAL_UNSTABLE)
                    }
                    let def = ast::MacroDef {
                        ident: it.ident,
                        attrs: it.attrs.clone(),
                        id: ast::DUMMY_NODE_ID,
                        span: it.span,
                        imported_from: None,
                        export: attr::contains_name(&it.attrs, "macro_export"),
                        use_locally: true,
                        allow_internal_unstable: allow_internal_unstable,
                        body: tts,
                    };
                    fld.cx.insert_macro(def);
                    // macro_rules! has a side effect but expands to nothing.
                    fld.cx.bt_pop();
                    return SmallVector::zero();
                }
                _ => {
                    fld.cx.span_err(it.span,
                                    &format!("{}! is not legal in item position",
                                            extname));
                    return SmallVector::zero();
                }
            }
        };
        expanded.make_items()
    };
    let items = match items {
        Some(items) => {
            items.into_iter()
                .map(|i| mark_item(i, fm))
                .flat_map(|i| fld.fold_item(i).into_iter())
                .collect()
        }
        None => {
            fld.cx.span_err(path_span,
                            &format!("non-item macro in item position: {}",
                                    extname));
            return SmallVector::zero();
        }
    };
    fld.cx.bt_pop();
    items
}
pub fn expand_item_mac ( it : P < ast :: Item > , fld : & mut MacroExpander ) -> SmallVector < P < ast :: Item > > { let ( extname , path_span , tts ) = match it . node { ItemMac ( codemap :: Spanned { node : MacInvocTT ( ref pth , ref tts , _ ) , .. } ) => { ( pth . segments [ 0 ] . identifier . name , pth . span , ( * tts ) . clone ( ) ) } _ => fld . cx . span_bug ( it . span , " " ) } ; let fm = fresh_mark ( ) ; let items = { let expanded = match fld . cx . syntax_env . find ( & extname ) { None => { fld . cx . span_err ( path_span , & format ! ( " " extname ) ) ; // let compilation continue return SmallVector :: zero ( ) ; } Some ( rc ) => match * rc { NormalTT ( ref expander , span , allow_internal_unstable ) => { if it . ident . name != parse :: token :: special_idents :: invalid . name { fld . cx . span_err ( path_span , & format ! ( " " extname it ident ) ) ; return SmallVector :: zero ( ) ; } fld . cx . bt_push ( ExpnInfo { call_site : it . span , callee : NameAndSpan { format : MacroBang ( extname ) , span : span , allow_internal_unstable : allow_internal_unstable , } } ) ; // mark before expansion: let marked_before = mark_tts ( & tts [ .. ] , fm ) ; expander . expand ( fld . cx , it . span , & marked_before [ .. ] ) } IdentTT ( ref expander , span , allow_internal_unstable ) => { if it . ident . name == parse :: token :: special_idents :: invalid . name { fld . cx . span_err ( path_span , & format ! ( " " extname ) ) ; return SmallVector :: zero ( ) ; } fld . cx . bt_push ( ExpnInfo { call_site : it . span , callee : NameAndSpan { format : MacroBang ( extname ) , span : span , allow_internal_unstable : allow_internal_unstable , } } ) ; // mark before expansion: let marked_tts = mark_tts ( & tts [ .. ] , fm ) ; expander . expand ( fld . cx , it . span , it . ident , marked_tts ) } MacroRulesTT => { if it . ident . name == parse :: token :: special_idents :: invalid . name { fld . cx . span_err ( path_span , & format ! ( " " ) ) ; return SmallVector :: zero ( ) ; } fld . cx . bt_push ( ExpnInfo { call_site : it . span , callee : NameAndSpan { format : MacroBang ( extname ) , span : None , // `macro_rules!` doesn't directly allow // unstable (this is orthogonal to whether // the macro it creates allows it) allow_internal_unstable : false , } } ) ; // DON'T mark before expansion. let allow_internal_unstable = attr :: contains_name ( & it . attrs , " " ) ; // ensure any #[allow_internal_unstable]s are // detected (including nested macro definitions // etc.) if allow_internal_unstable && ! fld . cx . ecfg . enable_allow_internal_unstable ( ) { feature_gate :: emit_feature_err ( & fld . cx . parse_sess . span_diagnostic , " " , it . span , feature_gate :: EXPLAIN_ALLOW_INTERNAL_UNSTABLE ) } let def = ast :: MacroDef { ident : it . ident , attrs : it . attrs . clone ( ) , id : ast :: DUMMY_NODE_ID , span : it . span , imported_from : None , export : attr :: contains_name ( & it . attrs , " " ) , use_locally : true , allow_internal_unstable : allow_internal_unstable , body : tts , } ; fld . cx . insert_macro ( def ) ; // macro_rules! has a side effect but expands to nothing. fld . cx . bt_pop ( ) ; return SmallVector :: zero ( ) ; } _ => { fld . cx . span_err ( it . span , & format ! ( " " extname ) ) ; return SmallVector :: zero ( ) ; } } } ; expanded . make_items ( ) } ; let items = match items { Some ( items ) => { items . into_iter ( ) . map ( | i | mark_item ( i , fm ) ) . flat_map ( | i | fld . fold_item ( i ) . into_iter ( ) ) . collect ( ) } None => { fld . cx . span_err ( path_span , & format ! ( " " extname ) ) ; return SmallVector :: zero ( ) ; } } ; fld . cx . bt_pop ( ) ; items }
Support for item-position macro invocations, exactly the same
logic as for expression-position macro invocations.
Support for item - position macro invocations exactly the same logic as for expression - position macro invocations .
it
P<ast::Item>
fld
&mut MacroExpander
it
P<ast::Item>
fld
&mut MacroExpander