133d722a9Sopenharmony_ciuse crate::syntax::attrs::OtherAttrs;
233d722a9Sopenharmony_ciuse crate::syntax::cfg::CfgExpr;
333d722a9Sopenharmony_ciuse crate::syntax::discriminant::DiscriminantSet;
433d722a9Sopenharmony_ciuse crate::syntax::file::{Item, ItemForeignMod};
533d722a9Sopenharmony_ciuse crate::syntax::report::Errors;
633d722a9Sopenharmony_ciuse crate::syntax::Atom::*;
733d722a9Sopenharmony_ciuse crate::syntax::{
833d722a9Sopenharmony_ci    attrs, error, Api, Array, Derive, Doc, Enum, EnumRepr, ExternFn, ExternType, ForeignName, Impl,
933d722a9Sopenharmony_ci    Include, IncludeKind, Lang, Lifetimes, NamedType, Namespace, Pair, Ptr, Receiver, Ref,
1033d722a9Sopenharmony_ci    Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var, Variant,
1133d722a9Sopenharmony_ci};
1233d722a9Sopenharmony_ciuse proc_macro2::{Delimiter, Group, Span, TokenStream, TokenTree};
1333d722a9Sopenharmony_ciuse quote::{format_ident, quote, quote_spanned};
1433d722a9Sopenharmony_ciuse std::mem;
1533d722a9Sopenharmony_ciuse syn::parse::{ParseStream, Parser};
1633d722a9Sopenharmony_ciuse syn::punctuated::Punctuated;
1733d722a9Sopenharmony_ciuse syn::{
1833d722a9Sopenharmony_ci    Abi, Attribute, Error, Expr, Fields, FnArg, ForeignItem, ForeignItemFn, ForeignItemType,
1933d722a9Sopenharmony_ci    GenericArgument, GenericParam, Generics, Ident, ItemEnum, ItemImpl, ItemStruct, Lit, LitStr,
2033d722a9Sopenharmony_ci    Pat, PathArguments, Result, ReturnType, Signature as RustSignature, Token, TraitBound,
2133d722a9Sopenharmony_ci    TraitBoundModifier, Type as RustType, TypeArray, TypeBareFn, TypeParamBound, TypePath, TypePtr,
2233d722a9Sopenharmony_ci    TypeReference, Variant as RustVariant, Visibility,
2333d722a9Sopenharmony_ci};
2433d722a9Sopenharmony_ci
2533d722a9Sopenharmony_cipub mod kw {
2633d722a9Sopenharmony_ci    syn::custom_keyword!(Pin);
2733d722a9Sopenharmony_ci    syn::custom_keyword!(Result);
2833d722a9Sopenharmony_ci}
2933d722a9Sopenharmony_ci
3033d722a9Sopenharmony_cipub fn parse_items(
3133d722a9Sopenharmony_ci    cx: &mut Errors,
3233d722a9Sopenharmony_ci    items: Vec<Item>,
3333d722a9Sopenharmony_ci    trusted: bool,
3433d722a9Sopenharmony_ci    namespace: &Namespace,
3533d722a9Sopenharmony_ci) -> Vec<Api> {
3633d722a9Sopenharmony_ci    let mut apis = Vec::new();
3733d722a9Sopenharmony_ci    for item in items {
3833d722a9Sopenharmony_ci        match item {
3933d722a9Sopenharmony_ci            Item::Struct(item) => match parse_struct(cx, item, namespace) {
4033d722a9Sopenharmony_ci                Ok(strct) => apis.push(strct),
4133d722a9Sopenharmony_ci                Err(err) => cx.push(err),
4233d722a9Sopenharmony_ci            },
4333d722a9Sopenharmony_ci            Item::Enum(item) => apis.push(parse_enum(cx, item, namespace)),
4433d722a9Sopenharmony_ci            Item::ForeignMod(foreign_mod) => {
4533d722a9Sopenharmony_ci                parse_foreign_mod(cx, foreign_mod, &mut apis, trusted, namespace)
4633d722a9Sopenharmony_ci            }
4733d722a9Sopenharmony_ci            Item::Impl(item) => match parse_impl(cx, item) {
4833d722a9Sopenharmony_ci                Ok(imp) => apis.push(imp),
4933d722a9Sopenharmony_ci                Err(err) => cx.push(err),
5033d722a9Sopenharmony_ci            },
5133d722a9Sopenharmony_ci            Item::Use(item) => cx.error(item, error::USE_NOT_ALLOWED),
5233d722a9Sopenharmony_ci            Item::Other(item) => cx.error(item, "unsupported item"),
5333d722a9Sopenharmony_ci        }
5433d722a9Sopenharmony_ci    }
5533d722a9Sopenharmony_ci    apis
5633d722a9Sopenharmony_ci}
5733d722a9Sopenharmony_ci
5833d722a9Sopenharmony_cifn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) -> Result<Api> {
5933d722a9Sopenharmony_ci    let mut cfg = CfgExpr::Unconditional;
6033d722a9Sopenharmony_ci    let mut doc = Doc::new();
6133d722a9Sopenharmony_ci    let mut derives = Vec::new();
6233d722a9Sopenharmony_ci    let mut namespace = namespace.clone();
6333d722a9Sopenharmony_ci    let mut cxx_name = None;
6433d722a9Sopenharmony_ci    let mut rust_name = None;
6533d722a9Sopenharmony_ci    let attrs = attrs::parse(
6633d722a9Sopenharmony_ci        cx,
6733d722a9Sopenharmony_ci        mem::take(&mut item.attrs),
6833d722a9Sopenharmony_ci        attrs::Parser {
6933d722a9Sopenharmony_ci            cfg: Some(&mut cfg),
7033d722a9Sopenharmony_ci            doc: Some(&mut doc),
7133d722a9Sopenharmony_ci            derives: Some(&mut derives),
7233d722a9Sopenharmony_ci            namespace: Some(&mut namespace),
7333d722a9Sopenharmony_ci            cxx_name: Some(&mut cxx_name),
7433d722a9Sopenharmony_ci            rust_name: Some(&mut rust_name),
7533d722a9Sopenharmony_ci            ..Default::default()
7633d722a9Sopenharmony_ci        },
7733d722a9Sopenharmony_ci    );
7833d722a9Sopenharmony_ci
7933d722a9Sopenharmony_ci    let named_fields = match item.fields {
8033d722a9Sopenharmony_ci        Fields::Named(fields) => fields,
8133d722a9Sopenharmony_ci        Fields::Unit => return Err(Error::new_spanned(item, "unit structs are not supported")),
8233d722a9Sopenharmony_ci        Fields::Unnamed(_) => {
8333d722a9Sopenharmony_ci            return Err(Error::new_spanned(item, "tuple structs are not supported"));
8433d722a9Sopenharmony_ci        }
8533d722a9Sopenharmony_ci    };
8633d722a9Sopenharmony_ci
8733d722a9Sopenharmony_ci    let mut lifetimes = Punctuated::new();
8833d722a9Sopenharmony_ci    let mut has_unsupported_generic_param = false;
8933d722a9Sopenharmony_ci    for pair in item.generics.params.into_pairs() {
9033d722a9Sopenharmony_ci        let (param, punct) = pair.into_tuple();
9133d722a9Sopenharmony_ci        match param {
9233d722a9Sopenharmony_ci            GenericParam::Lifetime(param) => {
9333d722a9Sopenharmony_ci                if !param.bounds.is_empty() && !has_unsupported_generic_param {
9433d722a9Sopenharmony_ci                    let msg = "lifetime parameter with bounds is not supported yet";
9533d722a9Sopenharmony_ci                    cx.error(&param, msg);
9633d722a9Sopenharmony_ci                    has_unsupported_generic_param = true;
9733d722a9Sopenharmony_ci                }
9833d722a9Sopenharmony_ci                lifetimes.push_value(param.lifetime);
9933d722a9Sopenharmony_ci                if let Some(punct) = punct {
10033d722a9Sopenharmony_ci                    lifetimes.push_punct(punct);
10133d722a9Sopenharmony_ci                }
10233d722a9Sopenharmony_ci            }
10333d722a9Sopenharmony_ci            GenericParam::Type(param) => {
10433d722a9Sopenharmony_ci                if !has_unsupported_generic_param {
10533d722a9Sopenharmony_ci                    let msg = "struct with generic type parameter is not supported yet";
10633d722a9Sopenharmony_ci                    cx.error(&param, msg);
10733d722a9Sopenharmony_ci                    has_unsupported_generic_param = true;
10833d722a9Sopenharmony_ci                }
10933d722a9Sopenharmony_ci            }
11033d722a9Sopenharmony_ci            GenericParam::Const(param) => {
11133d722a9Sopenharmony_ci                if !has_unsupported_generic_param {
11233d722a9Sopenharmony_ci                    let msg = "struct with const generic parameter is not supported yet";
11333d722a9Sopenharmony_ci                    cx.error(&param, msg);
11433d722a9Sopenharmony_ci                    has_unsupported_generic_param = true;
11533d722a9Sopenharmony_ci                }
11633d722a9Sopenharmony_ci            }
11733d722a9Sopenharmony_ci        }
11833d722a9Sopenharmony_ci    }
11933d722a9Sopenharmony_ci
12033d722a9Sopenharmony_ci    if let Some(where_clause) = &item.generics.where_clause {
12133d722a9Sopenharmony_ci        cx.error(
12233d722a9Sopenharmony_ci            where_clause,
12333d722a9Sopenharmony_ci            "struct with where-clause is not supported yet",
12433d722a9Sopenharmony_ci        );
12533d722a9Sopenharmony_ci    }
12633d722a9Sopenharmony_ci
12733d722a9Sopenharmony_ci    let mut fields = Vec::new();
12833d722a9Sopenharmony_ci    for field in named_fields.named {
12933d722a9Sopenharmony_ci        let ident = field.ident.unwrap();
13033d722a9Sopenharmony_ci        let mut cfg = CfgExpr::Unconditional;
13133d722a9Sopenharmony_ci        let mut doc = Doc::new();
13233d722a9Sopenharmony_ci        let mut cxx_name = None;
13333d722a9Sopenharmony_ci        let mut rust_name = None;
13433d722a9Sopenharmony_ci        let attrs = attrs::parse(
13533d722a9Sopenharmony_ci            cx,
13633d722a9Sopenharmony_ci            field.attrs,
13733d722a9Sopenharmony_ci            attrs::Parser {
13833d722a9Sopenharmony_ci                cfg: Some(&mut cfg),
13933d722a9Sopenharmony_ci                doc: Some(&mut doc),
14033d722a9Sopenharmony_ci                cxx_name: Some(&mut cxx_name),
14133d722a9Sopenharmony_ci                rust_name: Some(&mut rust_name),
14233d722a9Sopenharmony_ci                ..Default::default()
14333d722a9Sopenharmony_ci            },
14433d722a9Sopenharmony_ci        );
14533d722a9Sopenharmony_ci        let ty = match parse_type(&field.ty) {
14633d722a9Sopenharmony_ci            Ok(ty) => ty,
14733d722a9Sopenharmony_ci            Err(err) => {
14833d722a9Sopenharmony_ci                cx.push(err);
14933d722a9Sopenharmony_ci                continue;
15033d722a9Sopenharmony_ci            }
15133d722a9Sopenharmony_ci        };
15233d722a9Sopenharmony_ci        let visibility = visibility_pub(&field.vis, ident.span());
15333d722a9Sopenharmony_ci        let name = pair(Namespace::default(), &ident, cxx_name, rust_name);
15433d722a9Sopenharmony_ci        let colon_token = field.colon_token.unwrap();
15533d722a9Sopenharmony_ci        fields.push(Var {
15633d722a9Sopenharmony_ci            cfg,
15733d722a9Sopenharmony_ci            doc,
15833d722a9Sopenharmony_ci            attrs,
15933d722a9Sopenharmony_ci            visibility,
16033d722a9Sopenharmony_ci            name,
16133d722a9Sopenharmony_ci            colon_token,
16233d722a9Sopenharmony_ci            ty,
16333d722a9Sopenharmony_ci        });
16433d722a9Sopenharmony_ci    }
16533d722a9Sopenharmony_ci
16633d722a9Sopenharmony_ci    let struct_token = item.struct_token;
16733d722a9Sopenharmony_ci    let visibility = visibility_pub(&item.vis, struct_token.span);
16833d722a9Sopenharmony_ci    let name = pair(namespace, &item.ident, cxx_name, rust_name);
16933d722a9Sopenharmony_ci    let generics = Lifetimes {
17033d722a9Sopenharmony_ci        lt_token: item.generics.lt_token,
17133d722a9Sopenharmony_ci        lifetimes,
17233d722a9Sopenharmony_ci        gt_token: item.generics.gt_token,
17333d722a9Sopenharmony_ci    };
17433d722a9Sopenharmony_ci    let brace_token = named_fields.brace_token;
17533d722a9Sopenharmony_ci
17633d722a9Sopenharmony_ci    Ok(Api::Struct(Struct {
17733d722a9Sopenharmony_ci        cfg,
17833d722a9Sopenharmony_ci        doc,
17933d722a9Sopenharmony_ci        derives,
18033d722a9Sopenharmony_ci        attrs,
18133d722a9Sopenharmony_ci        visibility,
18233d722a9Sopenharmony_ci        struct_token,
18333d722a9Sopenharmony_ci        name,
18433d722a9Sopenharmony_ci        generics,
18533d722a9Sopenharmony_ci        brace_token,
18633d722a9Sopenharmony_ci        fields,
18733d722a9Sopenharmony_ci    }))
18833d722a9Sopenharmony_ci}
18933d722a9Sopenharmony_ci
19033d722a9Sopenharmony_cifn parse_enum(cx: &mut Errors, item: ItemEnum, namespace: &Namespace) -> Api {
19133d722a9Sopenharmony_ci    let mut cfg = CfgExpr::Unconditional;
19233d722a9Sopenharmony_ci    let mut doc = Doc::new();
19333d722a9Sopenharmony_ci    let mut derives = Vec::new();
19433d722a9Sopenharmony_ci    let mut repr = None;
19533d722a9Sopenharmony_ci    let mut namespace = namespace.clone();
19633d722a9Sopenharmony_ci    let mut cxx_name = None;
19733d722a9Sopenharmony_ci    let mut rust_name = None;
19833d722a9Sopenharmony_ci    let mut variants_from_header = None;
19933d722a9Sopenharmony_ci    let attrs = attrs::parse(
20033d722a9Sopenharmony_ci        cx,
20133d722a9Sopenharmony_ci        item.attrs,
20233d722a9Sopenharmony_ci        attrs::Parser {
20333d722a9Sopenharmony_ci            cfg: Some(&mut cfg),
20433d722a9Sopenharmony_ci            doc: Some(&mut doc),
20533d722a9Sopenharmony_ci            derives: Some(&mut derives),
20633d722a9Sopenharmony_ci            repr: Some(&mut repr),
20733d722a9Sopenharmony_ci            namespace: Some(&mut namespace),
20833d722a9Sopenharmony_ci            cxx_name: Some(&mut cxx_name),
20933d722a9Sopenharmony_ci            rust_name: Some(&mut rust_name),
21033d722a9Sopenharmony_ci            variants_from_header: Some(&mut variants_from_header),
21133d722a9Sopenharmony_ci            ..Default::default()
21233d722a9Sopenharmony_ci        },
21333d722a9Sopenharmony_ci    );
21433d722a9Sopenharmony_ci
21533d722a9Sopenharmony_ci    if !item.generics.params.is_empty() {
21633d722a9Sopenharmony_ci        let vis = &item.vis;
21733d722a9Sopenharmony_ci        let enum_token = item.enum_token;
21833d722a9Sopenharmony_ci        let ident = &item.ident;
21933d722a9Sopenharmony_ci        let generics = &item.generics;
22033d722a9Sopenharmony_ci        let span = quote!(#vis #enum_token #ident #generics);
22133d722a9Sopenharmony_ci        cx.error(span, "enum with generic parameters is not supported");
22233d722a9Sopenharmony_ci    } else if let Some(where_clause) = &item.generics.where_clause {
22333d722a9Sopenharmony_ci        cx.error(where_clause, "enum with where-clause is not supported");
22433d722a9Sopenharmony_ci    }
22533d722a9Sopenharmony_ci
22633d722a9Sopenharmony_ci    let mut variants = Vec::new();
22733d722a9Sopenharmony_ci    let mut discriminants = DiscriminantSet::new(repr);
22833d722a9Sopenharmony_ci    for variant in item.variants {
22933d722a9Sopenharmony_ci        match parse_variant(cx, variant, &mut discriminants) {
23033d722a9Sopenharmony_ci            Ok(variant) => variants.push(variant),
23133d722a9Sopenharmony_ci            Err(err) => cx.push(err),
23233d722a9Sopenharmony_ci        }
23333d722a9Sopenharmony_ci    }
23433d722a9Sopenharmony_ci
23533d722a9Sopenharmony_ci    let enum_token = item.enum_token;
23633d722a9Sopenharmony_ci    let visibility = visibility_pub(&item.vis, enum_token.span);
23733d722a9Sopenharmony_ci    let brace_token = item.brace_token;
23833d722a9Sopenharmony_ci
23933d722a9Sopenharmony_ci    let explicit_repr = repr.is_some();
24033d722a9Sopenharmony_ci    let mut repr = U8;
24133d722a9Sopenharmony_ci    match discriminants.inferred_repr() {
24233d722a9Sopenharmony_ci        Ok(inferred) => repr = inferred,
24333d722a9Sopenharmony_ci        Err(err) => {
24433d722a9Sopenharmony_ci            let span = quote_spanned!(brace_token.span=> #enum_token {});
24533d722a9Sopenharmony_ci            cx.error(span, err);
24633d722a9Sopenharmony_ci            variants.clear();
24733d722a9Sopenharmony_ci        }
24833d722a9Sopenharmony_ci    }
24933d722a9Sopenharmony_ci
25033d722a9Sopenharmony_ci    let name = pair(namespace, &item.ident, cxx_name, rust_name);
25133d722a9Sopenharmony_ci    let repr_ident = Ident::new(repr.as_ref(), Span::call_site());
25233d722a9Sopenharmony_ci    let repr_type = Type::Ident(NamedType::new(repr_ident));
25333d722a9Sopenharmony_ci    let repr = EnumRepr::Native {
25433d722a9Sopenharmony_ci        atom: repr,
25533d722a9Sopenharmony_ci        repr_type,
25633d722a9Sopenharmony_ci    };
25733d722a9Sopenharmony_ci    let generics = Lifetimes {
25833d722a9Sopenharmony_ci        lt_token: None,
25933d722a9Sopenharmony_ci        lifetimes: Punctuated::new(),
26033d722a9Sopenharmony_ci        gt_token: None,
26133d722a9Sopenharmony_ci    };
26233d722a9Sopenharmony_ci    let variants_from_header_attr = variants_from_header;
26333d722a9Sopenharmony_ci    let variants_from_header = variants_from_header_attr.is_some();
26433d722a9Sopenharmony_ci
26533d722a9Sopenharmony_ci    Api::Enum(Enum {
26633d722a9Sopenharmony_ci        cfg,
26733d722a9Sopenharmony_ci        doc,
26833d722a9Sopenharmony_ci        derives,
26933d722a9Sopenharmony_ci        attrs,
27033d722a9Sopenharmony_ci        visibility,
27133d722a9Sopenharmony_ci        enum_token,
27233d722a9Sopenharmony_ci        name,
27333d722a9Sopenharmony_ci        generics,
27433d722a9Sopenharmony_ci        brace_token,
27533d722a9Sopenharmony_ci        variants,
27633d722a9Sopenharmony_ci        variants_from_header,
27733d722a9Sopenharmony_ci        variants_from_header_attr,
27833d722a9Sopenharmony_ci        repr,
27933d722a9Sopenharmony_ci        explicit_repr,
28033d722a9Sopenharmony_ci    })
28133d722a9Sopenharmony_ci}
28233d722a9Sopenharmony_ci
28333d722a9Sopenharmony_cifn parse_variant(
28433d722a9Sopenharmony_ci    cx: &mut Errors,
28533d722a9Sopenharmony_ci    mut variant: RustVariant,
28633d722a9Sopenharmony_ci    discriminants: &mut DiscriminantSet,
28733d722a9Sopenharmony_ci) -> Result<Variant> {
28833d722a9Sopenharmony_ci    let mut cfg = CfgExpr::Unconditional;
28933d722a9Sopenharmony_ci    let mut doc = Doc::new();
29033d722a9Sopenharmony_ci    let mut cxx_name = None;
29133d722a9Sopenharmony_ci    let mut rust_name = None;
29233d722a9Sopenharmony_ci    let attrs = attrs::parse(
29333d722a9Sopenharmony_ci        cx,
29433d722a9Sopenharmony_ci        mem::take(&mut variant.attrs),
29533d722a9Sopenharmony_ci        attrs::Parser {
29633d722a9Sopenharmony_ci            cfg: Some(&mut cfg),
29733d722a9Sopenharmony_ci            doc: Some(&mut doc),
29833d722a9Sopenharmony_ci            cxx_name: Some(&mut cxx_name),
29933d722a9Sopenharmony_ci            rust_name: Some(&mut rust_name),
30033d722a9Sopenharmony_ci            ..Default::default()
30133d722a9Sopenharmony_ci        },
30233d722a9Sopenharmony_ci    );
30333d722a9Sopenharmony_ci
30433d722a9Sopenharmony_ci    match variant.fields {
30533d722a9Sopenharmony_ci        Fields::Unit => {}
30633d722a9Sopenharmony_ci        _ => {
30733d722a9Sopenharmony_ci            let msg = "enums with data are not supported yet";
30833d722a9Sopenharmony_ci            return Err(Error::new_spanned(variant, msg));
30933d722a9Sopenharmony_ci        }
31033d722a9Sopenharmony_ci    }
31133d722a9Sopenharmony_ci
31233d722a9Sopenharmony_ci    let expr = variant.discriminant.as_ref().map(|(_, expr)| expr);
31333d722a9Sopenharmony_ci    let try_discriminant = match &expr {
31433d722a9Sopenharmony_ci        Some(lit) => discriminants.insert(lit),
31533d722a9Sopenharmony_ci        None => discriminants.insert_next(),
31633d722a9Sopenharmony_ci    };
31733d722a9Sopenharmony_ci    let discriminant = match try_discriminant {
31833d722a9Sopenharmony_ci        Ok(discriminant) => discriminant,
31933d722a9Sopenharmony_ci        Err(err) => return Err(Error::new_spanned(variant, err)),
32033d722a9Sopenharmony_ci    };
32133d722a9Sopenharmony_ci
32233d722a9Sopenharmony_ci    let name = pair(Namespace::ROOT, &variant.ident, cxx_name, rust_name);
32333d722a9Sopenharmony_ci    let expr = variant.discriminant.map(|(_, expr)| expr);
32433d722a9Sopenharmony_ci
32533d722a9Sopenharmony_ci    Ok(Variant {
32633d722a9Sopenharmony_ci        cfg,
32733d722a9Sopenharmony_ci        doc,
32833d722a9Sopenharmony_ci        attrs,
32933d722a9Sopenharmony_ci        name,
33033d722a9Sopenharmony_ci        discriminant,
33133d722a9Sopenharmony_ci        expr,
33233d722a9Sopenharmony_ci    })
33333d722a9Sopenharmony_ci}
33433d722a9Sopenharmony_ci
33533d722a9Sopenharmony_cifn parse_foreign_mod(
33633d722a9Sopenharmony_ci    cx: &mut Errors,
33733d722a9Sopenharmony_ci    foreign_mod: ItemForeignMod,
33833d722a9Sopenharmony_ci    out: &mut Vec<Api>,
33933d722a9Sopenharmony_ci    trusted: bool,
34033d722a9Sopenharmony_ci    namespace: &Namespace,
34133d722a9Sopenharmony_ci) {
34233d722a9Sopenharmony_ci    let lang = match parse_lang(&foreign_mod.abi) {
34333d722a9Sopenharmony_ci        Ok(lang) => lang,
34433d722a9Sopenharmony_ci        Err(err) => return cx.push(err),
34533d722a9Sopenharmony_ci    };
34633d722a9Sopenharmony_ci
34733d722a9Sopenharmony_ci    match lang {
34833d722a9Sopenharmony_ci        Lang::Rust => {
34933d722a9Sopenharmony_ci            if foreign_mod.unsafety.is_some() {
35033d722a9Sopenharmony_ci                let unsafety = foreign_mod.unsafety;
35133d722a9Sopenharmony_ci                let abi = &foreign_mod.abi;
35233d722a9Sopenharmony_ci                let span = quote!(#unsafety #abi);
35333d722a9Sopenharmony_ci                cx.error(span, "extern \"Rust\" block does not need to be unsafe");
35433d722a9Sopenharmony_ci            }
35533d722a9Sopenharmony_ci        }
35633d722a9Sopenharmony_ci        Lang::Cxx => {}
35733d722a9Sopenharmony_ci    }
35833d722a9Sopenharmony_ci
35933d722a9Sopenharmony_ci    let trusted = trusted || foreign_mod.unsafety.is_some();
36033d722a9Sopenharmony_ci
36133d722a9Sopenharmony_ci    let mut cfg = CfgExpr::Unconditional;
36233d722a9Sopenharmony_ci    let mut namespace = namespace.clone();
36333d722a9Sopenharmony_ci    let attrs = attrs::parse(
36433d722a9Sopenharmony_ci        cx,
36533d722a9Sopenharmony_ci        foreign_mod.attrs,
36633d722a9Sopenharmony_ci        attrs::Parser {
36733d722a9Sopenharmony_ci            cfg: Some(&mut cfg),
36833d722a9Sopenharmony_ci            namespace: Some(&mut namespace),
36933d722a9Sopenharmony_ci            ..Default::default()
37033d722a9Sopenharmony_ci        },
37133d722a9Sopenharmony_ci    );
37233d722a9Sopenharmony_ci
37333d722a9Sopenharmony_ci    let mut items = Vec::new();
37433d722a9Sopenharmony_ci    for foreign in foreign_mod.items {
37533d722a9Sopenharmony_ci        match foreign {
37633d722a9Sopenharmony_ci            ForeignItem::Type(foreign) => {
37733d722a9Sopenharmony_ci                let ety = parse_extern_type(cx, foreign, lang, trusted, &cfg, &namespace, &attrs);
37833d722a9Sopenharmony_ci                items.push(ety);
37933d722a9Sopenharmony_ci            }
38033d722a9Sopenharmony_ci            ForeignItem::Fn(foreign) => {
38133d722a9Sopenharmony_ci                match parse_extern_fn(cx, foreign, lang, trusted, &cfg, &namespace, &attrs) {
38233d722a9Sopenharmony_ci                    Ok(efn) => items.push(efn),
38333d722a9Sopenharmony_ci                    Err(err) => cx.push(err),
38433d722a9Sopenharmony_ci                }
38533d722a9Sopenharmony_ci            }
38633d722a9Sopenharmony_ci            ForeignItem::Macro(foreign) if foreign.mac.path.is_ident("include") => {
38733d722a9Sopenharmony_ci                match foreign.mac.parse_body_with(parse_include) {
38833d722a9Sopenharmony_ci                    Ok(mut include) => {
38933d722a9Sopenharmony_ci                        include.cfg = cfg.clone();
39033d722a9Sopenharmony_ci                        items.push(Api::Include(include));
39133d722a9Sopenharmony_ci                    }
39233d722a9Sopenharmony_ci                    Err(err) => cx.push(err),
39333d722a9Sopenharmony_ci                }
39433d722a9Sopenharmony_ci            }
39533d722a9Sopenharmony_ci            ForeignItem::Verbatim(tokens) => {
39633d722a9Sopenharmony_ci                match parse_extern_verbatim(cx, tokens, lang, trusted, &cfg, &namespace, &attrs) {
39733d722a9Sopenharmony_ci                    Ok(api) => items.push(api),
39833d722a9Sopenharmony_ci                    Err(err) => cx.push(err),
39933d722a9Sopenharmony_ci                }
40033d722a9Sopenharmony_ci            }
40133d722a9Sopenharmony_ci            _ => cx.error(foreign, "unsupported foreign item"),
40233d722a9Sopenharmony_ci        }
40333d722a9Sopenharmony_ci    }
40433d722a9Sopenharmony_ci
40533d722a9Sopenharmony_ci    if !trusted
40633d722a9Sopenharmony_ci        && items.iter().any(|api| match api {
40733d722a9Sopenharmony_ci            Api::CxxFunction(efn) => efn.unsafety.is_none(),
40833d722a9Sopenharmony_ci            _ => false,
40933d722a9Sopenharmony_ci        })
41033d722a9Sopenharmony_ci    {
41133d722a9Sopenharmony_ci        cx.error(
41233d722a9Sopenharmony_ci            foreign_mod.abi,
41333d722a9Sopenharmony_ci            "block must be declared `unsafe extern \"C++\"` if it contains any safe-to-call C++ functions",
41433d722a9Sopenharmony_ci        );
41533d722a9Sopenharmony_ci    }
41633d722a9Sopenharmony_ci
41733d722a9Sopenharmony_ci    let mut types = items.iter().filter_map(|item| match item {
41833d722a9Sopenharmony_ci        Api::CxxType(ety) | Api::RustType(ety) => Some(&ety.name),
41933d722a9Sopenharmony_ci        Api::TypeAlias(alias) => Some(&alias.name),
42033d722a9Sopenharmony_ci        _ => None,
42133d722a9Sopenharmony_ci    });
42233d722a9Sopenharmony_ci    if let (Some(single_type), None) = (types.next(), types.next()) {
42333d722a9Sopenharmony_ci        let single_type = single_type.clone();
42433d722a9Sopenharmony_ci        for item in &mut items {
42533d722a9Sopenharmony_ci            if let Api::CxxFunction(efn) | Api::RustFunction(efn) = item {
42633d722a9Sopenharmony_ci                if let Some(receiver) = &mut efn.receiver {
42733d722a9Sopenharmony_ci                    if receiver.ty.rust == "Self" {
42833d722a9Sopenharmony_ci                        receiver.ty.rust = single_type.rust.clone();
42933d722a9Sopenharmony_ci                    }
43033d722a9Sopenharmony_ci                }
43133d722a9Sopenharmony_ci            }
43233d722a9Sopenharmony_ci        }
43333d722a9Sopenharmony_ci    }
43433d722a9Sopenharmony_ci
43533d722a9Sopenharmony_ci    out.extend(items);
43633d722a9Sopenharmony_ci}
43733d722a9Sopenharmony_ci
43833d722a9Sopenharmony_cifn parse_lang(abi: &Abi) -> Result<Lang> {
43933d722a9Sopenharmony_ci    let name = match &abi.name {
44033d722a9Sopenharmony_ci        Some(name) => name,
44133d722a9Sopenharmony_ci        None => {
44233d722a9Sopenharmony_ci            return Err(Error::new_spanned(
44333d722a9Sopenharmony_ci                abi,
44433d722a9Sopenharmony_ci                "ABI name is required, extern \"C++\" or extern \"Rust\"",
44533d722a9Sopenharmony_ci            ));
44633d722a9Sopenharmony_ci        }
44733d722a9Sopenharmony_ci    };
44833d722a9Sopenharmony_ci
44933d722a9Sopenharmony_ci    match name.value().as_str() {
45033d722a9Sopenharmony_ci        "C++" => Ok(Lang::Cxx),
45133d722a9Sopenharmony_ci        "Rust" => Ok(Lang::Rust),
45233d722a9Sopenharmony_ci        _ => Err(Error::new_spanned(
45333d722a9Sopenharmony_ci            abi,
45433d722a9Sopenharmony_ci            "unrecognized ABI, requires either \"C++\" or \"Rust\"",
45533d722a9Sopenharmony_ci        )),
45633d722a9Sopenharmony_ci    }
45733d722a9Sopenharmony_ci}
45833d722a9Sopenharmony_ci
45933d722a9Sopenharmony_cifn parse_extern_type(
46033d722a9Sopenharmony_ci    cx: &mut Errors,
46133d722a9Sopenharmony_ci    foreign_type: ForeignItemType,
46233d722a9Sopenharmony_ci    lang: Lang,
46333d722a9Sopenharmony_ci    trusted: bool,
46433d722a9Sopenharmony_ci    extern_block_cfg: &CfgExpr,
46533d722a9Sopenharmony_ci    namespace: &Namespace,
46633d722a9Sopenharmony_ci    attrs: &OtherAttrs,
46733d722a9Sopenharmony_ci) -> Api {
46833d722a9Sopenharmony_ci    let mut cfg = extern_block_cfg.clone();
46933d722a9Sopenharmony_ci    let mut doc = Doc::new();
47033d722a9Sopenharmony_ci    let mut derives = Vec::new();
47133d722a9Sopenharmony_ci    let mut namespace = namespace.clone();
47233d722a9Sopenharmony_ci    let mut cxx_name = None;
47333d722a9Sopenharmony_ci    let mut rust_name = None;
47433d722a9Sopenharmony_ci    let mut attrs = attrs.clone();
47533d722a9Sopenharmony_ci    attrs.extend(attrs::parse(
47633d722a9Sopenharmony_ci        cx,
47733d722a9Sopenharmony_ci        foreign_type.attrs,
47833d722a9Sopenharmony_ci        attrs::Parser {
47933d722a9Sopenharmony_ci            cfg: Some(&mut cfg),
48033d722a9Sopenharmony_ci            doc: Some(&mut doc),
48133d722a9Sopenharmony_ci            derives: Some(&mut derives),
48233d722a9Sopenharmony_ci            namespace: Some(&mut namespace),
48333d722a9Sopenharmony_ci            cxx_name: Some(&mut cxx_name),
48433d722a9Sopenharmony_ci            rust_name: Some(&mut rust_name),
48533d722a9Sopenharmony_ci            ..Default::default()
48633d722a9Sopenharmony_ci        },
48733d722a9Sopenharmony_ci    ));
48833d722a9Sopenharmony_ci
48933d722a9Sopenharmony_ci    let type_token = foreign_type.type_token;
49033d722a9Sopenharmony_ci    let visibility = visibility_pub(&foreign_type.vis, type_token.span);
49133d722a9Sopenharmony_ci    let name = pair(namespace, &foreign_type.ident, cxx_name, rust_name);
49233d722a9Sopenharmony_ci    let generics = extern_type_lifetimes(cx, foreign_type.generics);
49333d722a9Sopenharmony_ci    let colon_token = None;
49433d722a9Sopenharmony_ci    let bounds = Vec::new();
49533d722a9Sopenharmony_ci    let semi_token = foreign_type.semi_token;
49633d722a9Sopenharmony_ci
49733d722a9Sopenharmony_ci    (match lang {
49833d722a9Sopenharmony_ci        Lang::Cxx => Api::CxxType,
49933d722a9Sopenharmony_ci        Lang::Rust => Api::RustType,
50033d722a9Sopenharmony_ci    })(ExternType {
50133d722a9Sopenharmony_ci        cfg,
50233d722a9Sopenharmony_ci        lang,
50333d722a9Sopenharmony_ci        doc,
50433d722a9Sopenharmony_ci        derives,
50533d722a9Sopenharmony_ci        attrs,
50633d722a9Sopenharmony_ci        visibility,
50733d722a9Sopenharmony_ci        type_token,
50833d722a9Sopenharmony_ci        name,
50933d722a9Sopenharmony_ci        generics,
51033d722a9Sopenharmony_ci        colon_token,
51133d722a9Sopenharmony_ci        bounds,
51233d722a9Sopenharmony_ci        semi_token,
51333d722a9Sopenharmony_ci        trusted,
51433d722a9Sopenharmony_ci    })
51533d722a9Sopenharmony_ci}
51633d722a9Sopenharmony_ci
51733d722a9Sopenharmony_cifn parse_extern_fn(
51833d722a9Sopenharmony_ci    cx: &mut Errors,
51933d722a9Sopenharmony_ci    mut foreign_fn: ForeignItemFn,
52033d722a9Sopenharmony_ci    lang: Lang,
52133d722a9Sopenharmony_ci    trusted: bool,
52233d722a9Sopenharmony_ci    extern_block_cfg: &CfgExpr,
52333d722a9Sopenharmony_ci    namespace: &Namespace,
52433d722a9Sopenharmony_ci    attrs: &OtherAttrs,
52533d722a9Sopenharmony_ci) -> Result<Api> {
52633d722a9Sopenharmony_ci    let mut cfg = extern_block_cfg.clone();
52733d722a9Sopenharmony_ci    let mut doc = Doc::new();
52833d722a9Sopenharmony_ci    let mut namespace = namespace.clone();
52933d722a9Sopenharmony_ci    let mut cxx_name = None;
53033d722a9Sopenharmony_ci    let mut rust_name = None;
53133d722a9Sopenharmony_ci    let mut attrs = attrs.clone();
53233d722a9Sopenharmony_ci    attrs.extend(attrs::parse(
53333d722a9Sopenharmony_ci        cx,
53433d722a9Sopenharmony_ci        mem::take(&mut foreign_fn.attrs),
53533d722a9Sopenharmony_ci        attrs::Parser {
53633d722a9Sopenharmony_ci            cfg: Some(&mut cfg),
53733d722a9Sopenharmony_ci            doc: Some(&mut doc),
53833d722a9Sopenharmony_ci            namespace: Some(&mut namespace),
53933d722a9Sopenharmony_ci            cxx_name: Some(&mut cxx_name),
54033d722a9Sopenharmony_ci            rust_name: Some(&mut rust_name),
54133d722a9Sopenharmony_ci            ..Default::default()
54233d722a9Sopenharmony_ci        },
54333d722a9Sopenharmony_ci    ));
54433d722a9Sopenharmony_ci
54533d722a9Sopenharmony_ci    let generics = &foreign_fn.sig.generics;
54633d722a9Sopenharmony_ci    if generics.where_clause.is_some()
54733d722a9Sopenharmony_ci        || generics.params.iter().any(|param| match param {
54833d722a9Sopenharmony_ci            GenericParam::Lifetime(lifetime) => !lifetime.bounds.is_empty(),
54933d722a9Sopenharmony_ci            GenericParam::Type(_) | GenericParam::Const(_) => true,
55033d722a9Sopenharmony_ci        })
55133d722a9Sopenharmony_ci    {
55233d722a9Sopenharmony_ci        return Err(Error::new_spanned(
55333d722a9Sopenharmony_ci            foreign_fn,
55433d722a9Sopenharmony_ci            "extern function with generic parameters is not supported yet",
55533d722a9Sopenharmony_ci        ));
55633d722a9Sopenharmony_ci    }
55733d722a9Sopenharmony_ci
55833d722a9Sopenharmony_ci    if let Some(variadic) = &foreign_fn.sig.variadic {
55933d722a9Sopenharmony_ci        return Err(Error::new_spanned(
56033d722a9Sopenharmony_ci            variadic,
56133d722a9Sopenharmony_ci            "variadic function is not supported yet",
56233d722a9Sopenharmony_ci        ));
56333d722a9Sopenharmony_ci    }
56433d722a9Sopenharmony_ci
56533d722a9Sopenharmony_ci    if foreign_fn.sig.asyncness.is_some() && !cfg!(feature = "experimental-async-fn") {
56633d722a9Sopenharmony_ci        return Err(Error::new_spanned(
56733d722a9Sopenharmony_ci            foreign_fn,
56833d722a9Sopenharmony_ci            "async function is not directly supported yet, but see https://cxx.rs/async.html \
56933d722a9Sopenharmony_ci            for a working approach, and https://github.com/pcwalton/cxx-async for some helpers; \
57033d722a9Sopenharmony_ci            eventually what you wrote will work but it isn't integrated into the cxx::bridge \
57133d722a9Sopenharmony_ci            macro yet",
57233d722a9Sopenharmony_ci        ));
57333d722a9Sopenharmony_ci    }
57433d722a9Sopenharmony_ci
57533d722a9Sopenharmony_ci    if foreign_fn.sig.constness.is_some() {
57633d722a9Sopenharmony_ci        return Err(Error::new_spanned(
57733d722a9Sopenharmony_ci            foreign_fn,
57833d722a9Sopenharmony_ci            "const extern function is not supported",
57933d722a9Sopenharmony_ci        ));
58033d722a9Sopenharmony_ci    }
58133d722a9Sopenharmony_ci
58233d722a9Sopenharmony_ci    if let Some(abi) = &foreign_fn.sig.abi {
58333d722a9Sopenharmony_ci        return Err(Error::new_spanned(
58433d722a9Sopenharmony_ci            abi,
58533d722a9Sopenharmony_ci            "explicit ABI on extern function is not supported",
58633d722a9Sopenharmony_ci        ));
58733d722a9Sopenharmony_ci    }
58833d722a9Sopenharmony_ci
58933d722a9Sopenharmony_ci    let mut receiver = None;
59033d722a9Sopenharmony_ci    let mut args = Punctuated::new();
59133d722a9Sopenharmony_ci    for arg in foreign_fn.sig.inputs.pairs() {
59233d722a9Sopenharmony_ci        let (arg, comma) = arg.into_tuple();
59333d722a9Sopenharmony_ci        match arg {
59433d722a9Sopenharmony_ci            FnArg::Receiver(arg) => {
59533d722a9Sopenharmony_ci                if let Some((ampersand, lifetime)) = &arg.reference {
59633d722a9Sopenharmony_ci                    receiver = Some(Receiver {
59733d722a9Sopenharmony_ci                        pinned: false,
59833d722a9Sopenharmony_ci                        ampersand: *ampersand,
59933d722a9Sopenharmony_ci                        lifetime: lifetime.clone(),
60033d722a9Sopenharmony_ci                        mutable: arg.mutability.is_some(),
60133d722a9Sopenharmony_ci                        var: arg.self_token,
60233d722a9Sopenharmony_ci                        colon_token: Token![:](arg.self_token.span),
60333d722a9Sopenharmony_ci                        ty: NamedType::new(Ident::new("Self", arg.self_token.span)),
60433d722a9Sopenharmony_ci                        shorthand: true,
60533d722a9Sopenharmony_ci                        pin_tokens: None,
60633d722a9Sopenharmony_ci                        mutability: arg.mutability,
60733d722a9Sopenharmony_ci                    });
60833d722a9Sopenharmony_ci                    continue;
60933d722a9Sopenharmony_ci                }
61033d722a9Sopenharmony_ci                if let Some(colon_token) = arg.colon_token {
61133d722a9Sopenharmony_ci                    let ty = parse_type(&arg.ty)?;
61233d722a9Sopenharmony_ci                    if let Type::Ref(reference) = ty {
61333d722a9Sopenharmony_ci                        if let Type::Ident(ident) = reference.inner {
61433d722a9Sopenharmony_ci                            receiver = Some(Receiver {
61533d722a9Sopenharmony_ci                                pinned: reference.pinned,
61633d722a9Sopenharmony_ci                                ampersand: reference.ampersand,
61733d722a9Sopenharmony_ci                                lifetime: reference.lifetime,
61833d722a9Sopenharmony_ci                                mutable: reference.mutable,
61933d722a9Sopenharmony_ci                                var: Token![self](ident.rust.span()),
62033d722a9Sopenharmony_ci                                colon_token,
62133d722a9Sopenharmony_ci                                ty: ident,
62233d722a9Sopenharmony_ci                                shorthand: false,
62333d722a9Sopenharmony_ci                                pin_tokens: reference.pin_tokens,
62433d722a9Sopenharmony_ci                                mutability: reference.mutability,
62533d722a9Sopenharmony_ci                            });
62633d722a9Sopenharmony_ci                            continue;
62733d722a9Sopenharmony_ci                        }
62833d722a9Sopenharmony_ci                    }
62933d722a9Sopenharmony_ci                }
63033d722a9Sopenharmony_ci                return Err(Error::new_spanned(arg, "unsupported method receiver"));
63133d722a9Sopenharmony_ci            }
63233d722a9Sopenharmony_ci            FnArg::Typed(arg) => {
63333d722a9Sopenharmony_ci                let ident = match arg.pat.as_ref() {
63433d722a9Sopenharmony_ci                    Pat::Ident(pat) => pat.ident.clone(),
63533d722a9Sopenharmony_ci                    Pat::Wild(pat) => {
63633d722a9Sopenharmony_ci                        Ident::new(&format!("arg{}", args.len()), pat.underscore_token.span)
63733d722a9Sopenharmony_ci                    }
63833d722a9Sopenharmony_ci                    _ => return Err(Error::new_spanned(arg, "unsupported signature")),
63933d722a9Sopenharmony_ci                };
64033d722a9Sopenharmony_ci                let ty = parse_type(&arg.ty)?;
64133d722a9Sopenharmony_ci                let cfg = CfgExpr::Unconditional;
64233d722a9Sopenharmony_ci                let doc = Doc::new();
64333d722a9Sopenharmony_ci                let attrs = OtherAttrs::none();
64433d722a9Sopenharmony_ci                let visibility = Token![pub](ident.span());
64533d722a9Sopenharmony_ci                let name = pair(Namespace::default(), &ident, None, None);
64633d722a9Sopenharmony_ci                let colon_token = arg.colon_token;
64733d722a9Sopenharmony_ci                args.push_value(Var {
64833d722a9Sopenharmony_ci                    cfg,
64933d722a9Sopenharmony_ci                    doc,
65033d722a9Sopenharmony_ci                    attrs,
65133d722a9Sopenharmony_ci                    visibility,
65233d722a9Sopenharmony_ci                    name,
65333d722a9Sopenharmony_ci                    colon_token,
65433d722a9Sopenharmony_ci                    ty,
65533d722a9Sopenharmony_ci                });
65633d722a9Sopenharmony_ci                if let Some(comma) = comma {
65733d722a9Sopenharmony_ci                    args.push_punct(*comma);
65833d722a9Sopenharmony_ci                }
65933d722a9Sopenharmony_ci            }
66033d722a9Sopenharmony_ci        }
66133d722a9Sopenharmony_ci    }
66233d722a9Sopenharmony_ci
66333d722a9Sopenharmony_ci    let mut throws_tokens = None;
66433d722a9Sopenharmony_ci    let ret = parse_return_type(&foreign_fn.sig.output, &mut throws_tokens)?;
66533d722a9Sopenharmony_ci    let throws = throws_tokens.is_some();
66633d722a9Sopenharmony_ci    let asyncness = foreign_fn.sig.asyncness;
66733d722a9Sopenharmony_ci    let unsafety = foreign_fn.sig.unsafety;
66833d722a9Sopenharmony_ci    let fn_token = foreign_fn.sig.fn_token;
66933d722a9Sopenharmony_ci    let inherited_span = unsafety.map_or(fn_token.span, |unsafety| unsafety.span);
67033d722a9Sopenharmony_ci    let visibility = visibility_pub(&foreign_fn.vis, inherited_span);
67133d722a9Sopenharmony_ci    let name = pair(namespace, &foreign_fn.sig.ident, cxx_name, rust_name);
67233d722a9Sopenharmony_ci    let generics = generics.clone();
67333d722a9Sopenharmony_ci    let paren_token = foreign_fn.sig.paren_token;
67433d722a9Sopenharmony_ci    let semi_token = foreign_fn.semi_token;
67533d722a9Sopenharmony_ci
67633d722a9Sopenharmony_ci    Ok(match lang {
67733d722a9Sopenharmony_ci        Lang::Cxx => Api::CxxFunction,
67833d722a9Sopenharmony_ci        Lang::Rust => Api::RustFunction,
67933d722a9Sopenharmony_ci    }(ExternFn {
68033d722a9Sopenharmony_ci        cfg,
68133d722a9Sopenharmony_ci        lang,
68233d722a9Sopenharmony_ci        doc,
68333d722a9Sopenharmony_ci        attrs,
68433d722a9Sopenharmony_ci        visibility,
68533d722a9Sopenharmony_ci        name,
68633d722a9Sopenharmony_ci        sig: Signature {
68733d722a9Sopenharmony_ci            asyncness,
68833d722a9Sopenharmony_ci            unsafety,
68933d722a9Sopenharmony_ci            fn_token,
69033d722a9Sopenharmony_ci            generics,
69133d722a9Sopenharmony_ci            receiver,
69233d722a9Sopenharmony_ci            args,
69333d722a9Sopenharmony_ci            ret,
69433d722a9Sopenharmony_ci            throws,
69533d722a9Sopenharmony_ci            paren_token,
69633d722a9Sopenharmony_ci            throws_tokens,
69733d722a9Sopenharmony_ci        },
69833d722a9Sopenharmony_ci        semi_token,
69933d722a9Sopenharmony_ci        trusted,
70033d722a9Sopenharmony_ci    }))
70133d722a9Sopenharmony_ci}
70233d722a9Sopenharmony_ci
70333d722a9Sopenharmony_cifn parse_extern_verbatim(
70433d722a9Sopenharmony_ci    cx: &mut Errors,
70533d722a9Sopenharmony_ci    tokens: TokenStream,
70633d722a9Sopenharmony_ci    lang: Lang,
70733d722a9Sopenharmony_ci    trusted: bool,
70833d722a9Sopenharmony_ci    extern_block_cfg: &CfgExpr,
70933d722a9Sopenharmony_ci    namespace: &Namespace,
71033d722a9Sopenharmony_ci    attrs: &OtherAttrs,
71133d722a9Sopenharmony_ci) -> Result<Api> {
71233d722a9Sopenharmony_ci    |input: ParseStream| -> Result<Api> {
71333d722a9Sopenharmony_ci        let unparsed_attrs = input.call(Attribute::parse_outer)?;
71433d722a9Sopenharmony_ci        let visibility: Visibility = input.parse()?;
71533d722a9Sopenharmony_ci        if input.peek(Token![type]) {
71633d722a9Sopenharmony_ci            parse_extern_verbatim_type(
71733d722a9Sopenharmony_ci                cx,
71833d722a9Sopenharmony_ci                unparsed_attrs,
71933d722a9Sopenharmony_ci                visibility,
72033d722a9Sopenharmony_ci                input,
72133d722a9Sopenharmony_ci                lang,
72233d722a9Sopenharmony_ci                trusted,
72333d722a9Sopenharmony_ci                extern_block_cfg,
72433d722a9Sopenharmony_ci                namespace,
72533d722a9Sopenharmony_ci                attrs,
72633d722a9Sopenharmony_ci            )
72733d722a9Sopenharmony_ci        } else if input.peek(Token![fn]) {
72833d722a9Sopenharmony_ci            parse_extern_verbatim_fn(input)
72933d722a9Sopenharmony_ci        } else {
73033d722a9Sopenharmony_ci            let span = input.cursor().token_stream();
73133d722a9Sopenharmony_ci            Err(Error::new_spanned(
73233d722a9Sopenharmony_ci                span,
73333d722a9Sopenharmony_ci                "unsupported foreign item, expected `type` or `fn`",
73433d722a9Sopenharmony_ci            ))
73533d722a9Sopenharmony_ci        }
73633d722a9Sopenharmony_ci    }
73733d722a9Sopenharmony_ci    .parse2(tokens)
73833d722a9Sopenharmony_ci}
73933d722a9Sopenharmony_ci
74033d722a9Sopenharmony_cifn parse_extern_verbatim_type(
74133d722a9Sopenharmony_ci    cx: &mut Errors,
74233d722a9Sopenharmony_ci    unparsed_attrs: Vec<Attribute>,
74333d722a9Sopenharmony_ci    visibility: Visibility,
74433d722a9Sopenharmony_ci    input: ParseStream,
74533d722a9Sopenharmony_ci    lang: Lang,
74633d722a9Sopenharmony_ci    trusted: bool,
74733d722a9Sopenharmony_ci    extern_block_cfg: &CfgExpr,
74833d722a9Sopenharmony_ci    namespace: &Namespace,
74933d722a9Sopenharmony_ci    attrs: &OtherAttrs,
75033d722a9Sopenharmony_ci) -> Result<Api> {
75133d722a9Sopenharmony_ci    let type_token: Token![type] = input.parse()?;
75233d722a9Sopenharmony_ci    let ident: Ident = input.parse()?;
75333d722a9Sopenharmony_ci    let generics: Generics = input.parse()?;
75433d722a9Sopenharmony_ci    let lifetimes = extern_type_lifetimes(cx, generics);
75533d722a9Sopenharmony_ci    let lookahead = input.lookahead1();
75633d722a9Sopenharmony_ci    if lookahead.peek(Token![=]) {
75733d722a9Sopenharmony_ci        // type Alias = crate::path::to::Type;
75833d722a9Sopenharmony_ci        parse_type_alias(
75933d722a9Sopenharmony_ci            cx,
76033d722a9Sopenharmony_ci            unparsed_attrs,
76133d722a9Sopenharmony_ci            visibility,
76233d722a9Sopenharmony_ci            type_token,
76333d722a9Sopenharmony_ci            ident,
76433d722a9Sopenharmony_ci            lifetimes,
76533d722a9Sopenharmony_ci            input,
76633d722a9Sopenharmony_ci            lang,
76733d722a9Sopenharmony_ci            extern_block_cfg,
76833d722a9Sopenharmony_ci            namespace,
76933d722a9Sopenharmony_ci            attrs,
77033d722a9Sopenharmony_ci        )
77133d722a9Sopenharmony_ci    } else if lookahead.peek(Token![:]) {
77233d722a9Sopenharmony_ci        // type Opaque: Bound2 + Bound2;
77333d722a9Sopenharmony_ci        parse_extern_type_bounded(
77433d722a9Sopenharmony_ci            cx,
77533d722a9Sopenharmony_ci            unparsed_attrs,
77633d722a9Sopenharmony_ci            visibility,
77733d722a9Sopenharmony_ci            type_token,
77833d722a9Sopenharmony_ci            ident,
77933d722a9Sopenharmony_ci            lifetimes,
78033d722a9Sopenharmony_ci            input,
78133d722a9Sopenharmony_ci            lang,
78233d722a9Sopenharmony_ci            trusted,
78333d722a9Sopenharmony_ci            extern_block_cfg,
78433d722a9Sopenharmony_ci            namespace,
78533d722a9Sopenharmony_ci            attrs,
78633d722a9Sopenharmony_ci        )
78733d722a9Sopenharmony_ci    } else {
78833d722a9Sopenharmony_ci        Err(lookahead.error())
78933d722a9Sopenharmony_ci    }
79033d722a9Sopenharmony_ci}
79133d722a9Sopenharmony_ci
79233d722a9Sopenharmony_cifn extern_type_lifetimes(cx: &mut Errors, generics: Generics) -> Lifetimes {
79333d722a9Sopenharmony_ci    let mut lifetimes = Punctuated::new();
79433d722a9Sopenharmony_ci    let mut has_unsupported_generic_param = false;
79533d722a9Sopenharmony_ci    for pair in generics.params.into_pairs() {
79633d722a9Sopenharmony_ci        let (param, punct) = pair.into_tuple();
79733d722a9Sopenharmony_ci        match param {
79833d722a9Sopenharmony_ci            GenericParam::Lifetime(param) => {
79933d722a9Sopenharmony_ci                if !param.bounds.is_empty() && !has_unsupported_generic_param {
80033d722a9Sopenharmony_ci                    let msg = "lifetime parameter with bounds is not supported yet";
80133d722a9Sopenharmony_ci                    cx.error(&param, msg);
80233d722a9Sopenharmony_ci                    has_unsupported_generic_param = true;
80333d722a9Sopenharmony_ci                }
80433d722a9Sopenharmony_ci                lifetimes.push_value(param.lifetime);
80533d722a9Sopenharmony_ci                if let Some(punct) = punct {
80633d722a9Sopenharmony_ci                    lifetimes.push_punct(punct);
80733d722a9Sopenharmony_ci                }
80833d722a9Sopenharmony_ci            }
80933d722a9Sopenharmony_ci            GenericParam::Type(param) => {
81033d722a9Sopenharmony_ci                if !has_unsupported_generic_param {
81133d722a9Sopenharmony_ci                    let msg = "extern type with generic type parameter is not supported yet";
81233d722a9Sopenharmony_ci                    cx.error(&param, msg);
81333d722a9Sopenharmony_ci                    has_unsupported_generic_param = true;
81433d722a9Sopenharmony_ci                }
81533d722a9Sopenharmony_ci            }
81633d722a9Sopenharmony_ci            GenericParam::Const(param) => {
81733d722a9Sopenharmony_ci                if !has_unsupported_generic_param {
81833d722a9Sopenharmony_ci                    let msg = "extern type with const generic parameter is not supported yet";
81933d722a9Sopenharmony_ci                    cx.error(&param, msg);
82033d722a9Sopenharmony_ci                    has_unsupported_generic_param = true;
82133d722a9Sopenharmony_ci                }
82233d722a9Sopenharmony_ci            }
82333d722a9Sopenharmony_ci        }
82433d722a9Sopenharmony_ci    }
82533d722a9Sopenharmony_ci    Lifetimes {
82633d722a9Sopenharmony_ci        lt_token: generics.lt_token,
82733d722a9Sopenharmony_ci        lifetimes,
82833d722a9Sopenharmony_ci        gt_token: generics.gt_token,
82933d722a9Sopenharmony_ci    }
83033d722a9Sopenharmony_ci}
83133d722a9Sopenharmony_ci
83233d722a9Sopenharmony_cifn parse_extern_verbatim_fn(input: ParseStream) -> Result<Api> {
83333d722a9Sopenharmony_ci    input.parse::<RustSignature>()?;
83433d722a9Sopenharmony_ci    input.parse::<Token![;]>()?;
83533d722a9Sopenharmony_ci    unreachable!()
83633d722a9Sopenharmony_ci}
83733d722a9Sopenharmony_ci
83833d722a9Sopenharmony_cifn parse_type_alias(
83933d722a9Sopenharmony_ci    cx: &mut Errors,
84033d722a9Sopenharmony_ci    unparsed_attrs: Vec<Attribute>,
84133d722a9Sopenharmony_ci    visibility: Visibility,
84233d722a9Sopenharmony_ci    type_token: Token![type],
84333d722a9Sopenharmony_ci    ident: Ident,
84433d722a9Sopenharmony_ci    generics: Lifetimes,
84533d722a9Sopenharmony_ci    input: ParseStream,
84633d722a9Sopenharmony_ci    lang: Lang,
84733d722a9Sopenharmony_ci    extern_block_cfg: &CfgExpr,
84833d722a9Sopenharmony_ci    namespace: &Namespace,
84933d722a9Sopenharmony_ci    attrs: &OtherAttrs,
85033d722a9Sopenharmony_ci) -> Result<Api> {
85133d722a9Sopenharmony_ci    let eq_token: Token![=] = input.parse()?;
85233d722a9Sopenharmony_ci    let ty: RustType = input.parse()?;
85333d722a9Sopenharmony_ci    let semi_token: Token![;] = input.parse()?;
85433d722a9Sopenharmony_ci
85533d722a9Sopenharmony_ci    let mut cfg = extern_block_cfg.clone();
85633d722a9Sopenharmony_ci    let mut doc = Doc::new();
85733d722a9Sopenharmony_ci    let mut derives = Vec::new();
85833d722a9Sopenharmony_ci    let mut namespace = namespace.clone();
85933d722a9Sopenharmony_ci    let mut cxx_name = None;
86033d722a9Sopenharmony_ci    let mut rust_name = None;
86133d722a9Sopenharmony_ci    let mut attrs = attrs.clone();
86233d722a9Sopenharmony_ci    attrs.extend(attrs::parse(
86333d722a9Sopenharmony_ci        cx,
86433d722a9Sopenharmony_ci        unparsed_attrs,
86533d722a9Sopenharmony_ci        attrs::Parser {
86633d722a9Sopenharmony_ci            cfg: Some(&mut cfg),
86733d722a9Sopenharmony_ci            doc: Some(&mut doc),
86833d722a9Sopenharmony_ci            derives: Some(&mut derives),
86933d722a9Sopenharmony_ci            namespace: Some(&mut namespace),
87033d722a9Sopenharmony_ci            cxx_name: Some(&mut cxx_name),
87133d722a9Sopenharmony_ci            rust_name: Some(&mut rust_name),
87233d722a9Sopenharmony_ci            ..Default::default()
87333d722a9Sopenharmony_ci        },
87433d722a9Sopenharmony_ci    ));
87533d722a9Sopenharmony_ci
87633d722a9Sopenharmony_ci    if lang == Lang::Rust {
87733d722a9Sopenharmony_ci        let span = quote!(#type_token #semi_token);
87833d722a9Sopenharmony_ci        let msg = "type alias in extern \"Rust\" block is not supported";
87933d722a9Sopenharmony_ci        return Err(Error::new_spanned(span, msg));
88033d722a9Sopenharmony_ci    }
88133d722a9Sopenharmony_ci
88233d722a9Sopenharmony_ci    let visibility = visibility_pub(&visibility, type_token.span);
88333d722a9Sopenharmony_ci    let name = pair(namespace, &ident, cxx_name, rust_name);
88433d722a9Sopenharmony_ci
88533d722a9Sopenharmony_ci    Ok(Api::TypeAlias(TypeAlias {
88633d722a9Sopenharmony_ci        cfg,
88733d722a9Sopenharmony_ci        doc,
88833d722a9Sopenharmony_ci        derives,
88933d722a9Sopenharmony_ci        attrs,
89033d722a9Sopenharmony_ci        visibility,
89133d722a9Sopenharmony_ci        type_token,
89233d722a9Sopenharmony_ci        name,
89333d722a9Sopenharmony_ci        generics,
89433d722a9Sopenharmony_ci        eq_token,
89533d722a9Sopenharmony_ci        ty,
89633d722a9Sopenharmony_ci        semi_token,
89733d722a9Sopenharmony_ci    }))
89833d722a9Sopenharmony_ci}
89933d722a9Sopenharmony_ci
90033d722a9Sopenharmony_cifn parse_extern_type_bounded(
90133d722a9Sopenharmony_ci    cx: &mut Errors,
90233d722a9Sopenharmony_ci    unparsed_attrs: Vec<Attribute>,
90333d722a9Sopenharmony_ci    visibility: Visibility,
90433d722a9Sopenharmony_ci    type_token: Token![type],
90533d722a9Sopenharmony_ci    ident: Ident,
90633d722a9Sopenharmony_ci    generics: Lifetimes,
90733d722a9Sopenharmony_ci    input: ParseStream,
90833d722a9Sopenharmony_ci    lang: Lang,
90933d722a9Sopenharmony_ci    trusted: bool,
91033d722a9Sopenharmony_ci    extern_block_cfg: &CfgExpr,
91133d722a9Sopenharmony_ci    namespace: &Namespace,
91233d722a9Sopenharmony_ci    attrs: &OtherAttrs,
91333d722a9Sopenharmony_ci) -> Result<Api> {
91433d722a9Sopenharmony_ci    let mut bounds = Vec::new();
91533d722a9Sopenharmony_ci    let colon_token: Option<Token![:]> = input.parse()?;
91633d722a9Sopenharmony_ci    if colon_token.is_some() {
91733d722a9Sopenharmony_ci        loop {
91833d722a9Sopenharmony_ci            match input.parse()? {
91933d722a9Sopenharmony_ci                TypeParamBound::Trait(TraitBound {
92033d722a9Sopenharmony_ci                    paren_token: None,
92133d722a9Sopenharmony_ci                    modifier: TraitBoundModifier::None,
92233d722a9Sopenharmony_ci                    lifetimes: None,
92333d722a9Sopenharmony_ci                    path,
92433d722a9Sopenharmony_ci                }) if if let Some(derive) = path.get_ident().and_then(Derive::from) {
92533d722a9Sopenharmony_ci                    bounds.push(derive);
92633d722a9Sopenharmony_ci                    true
92733d722a9Sopenharmony_ci                } else {
92833d722a9Sopenharmony_ci                    false
92933d722a9Sopenharmony_ci                } => {}
93033d722a9Sopenharmony_ci                bound => cx.error(bound, "unsupported trait"),
93133d722a9Sopenharmony_ci            }
93233d722a9Sopenharmony_ci
93333d722a9Sopenharmony_ci            let lookahead = input.lookahead1();
93433d722a9Sopenharmony_ci            if lookahead.peek(Token![+]) {
93533d722a9Sopenharmony_ci                input.parse::<Token![+]>()?;
93633d722a9Sopenharmony_ci            } else if lookahead.peek(Token![;]) {
93733d722a9Sopenharmony_ci                break;
93833d722a9Sopenharmony_ci            } else {
93933d722a9Sopenharmony_ci                return Err(lookahead.error());
94033d722a9Sopenharmony_ci            }
94133d722a9Sopenharmony_ci        }
94233d722a9Sopenharmony_ci    }
94333d722a9Sopenharmony_ci    let semi_token: Token![;] = input.parse()?;
94433d722a9Sopenharmony_ci
94533d722a9Sopenharmony_ci    let mut cfg = extern_block_cfg.clone();
94633d722a9Sopenharmony_ci    let mut doc = Doc::new();
94733d722a9Sopenharmony_ci    let mut derives = Vec::new();
94833d722a9Sopenharmony_ci    let mut namespace = namespace.clone();
94933d722a9Sopenharmony_ci    let mut cxx_name = None;
95033d722a9Sopenharmony_ci    let mut rust_name = None;
95133d722a9Sopenharmony_ci    let mut attrs = attrs.clone();
95233d722a9Sopenharmony_ci    attrs.extend(attrs::parse(
95333d722a9Sopenharmony_ci        cx,
95433d722a9Sopenharmony_ci        unparsed_attrs,
95533d722a9Sopenharmony_ci        attrs::Parser {
95633d722a9Sopenharmony_ci            cfg: Some(&mut cfg),
95733d722a9Sopenharmony_ci            doc: Some(&mut doc),
95833d722a9Sopenharmony_ci            derives: Some(&mut derives),
95933d722a9Sopenharmony_ci            namespace: Some(&mut namespace),
96033d722a9Sopenharmony_ci            cxx_name: Some(&mut cxx_name),
96133d722a9Sopenharmony_ci            rust_name: Some(&mut rust_name),
96233d722a9Sopenharmony_ci            ..Default::default()
96333d722a9Sopenharmony_ci        },
96433d722a9Sopenharmony_ci    ));
96533d722a9Sopenharmony_ci
96633d722a9Sopenharmony_ci    let visibility = visibility_pub(&visibility, type_token.span);
96733d722a9Sopenharmony_ci    let name = pair(namespace, &ident, cxx_name, rust_name);
96833d722a9Sopenharmony_ci
96933d722a9Sopenharmony_ci    Ok(match lang {
97033d722a9Sopenharmony_ci        Lang::Cxx => Api::CxxType,
97133d722a9Sopenharmony_ci        Lang::Rust => Api::RustType,
97233d722a9Sopenharmony_ci    }(ExternType {
97333d722a9Sopenharmony_ci        cfg,
97433d722a9Sopenharmony_ci        lang,
97533d722a9Sopenharmony_ci        doc,
97633d722a9Sopenharmony_ci        derives,
97733d722a9Sopenharmony_ci        attrs,
97833d722a9Sopenharmony_ci        visibility,
97933d722a9Sopenharmony_ci        type_token,
98033d722a9Sopenharmony_ci        name,
98133d722a9Sopenharmony_ci        generics,
98233d722a9Sopenharmony_ci        colon_token,
98333d722a9Sopenharmony_ci        bounds,
98433d722a9Sopenharmony_ci        semi_token,
98533d722a9Sopenharmony_ci        trusted,
98633d722a9Sopenharmony_ci    }))
98733d722a9Sopenharmony_ci}
98833d722a9Sopenharmony_ci
98933d722a9Sopenharmony_cifn parse_impl(cx: &mut Errors, imp: ItemImpl) -> Result<Api> {
99033d722a9Sopenharmony_ci    let impl_token = imp.impl_token;
99133d722a9Sopenharmony_ci
99233d722a9Sopenharmony_ci    let mut cfg = CfgExpr::Unconditional;
99333d722a9Sopenharmony_ci    attrs::parse(
99433d722a9Sopenharmony_ci        cx,
99533d722a9Sopenharmony_ci        imp.attrs,
99633d722a9Sopenharmony_ci        attrs::Parser {
99733d722a9Sopenharmony_ci            cfg: Some(&mut cfg),
99833d722a9Sopenharmony_ci            ..Default::default()
99933d722a9Sopenharmony_ci        },
100033d722a9Sopenharmony_ci    );
100133d722a9Sopenharmony_ci
100233d722a9Sopenharmony_ci    if !imp.items.is_empty() {
100333d722a9Sopenharmony_ci        let mut span = Group::new(Delimiter::Brace, TokenStream::new());
100433d722a9Sopenharmony_ci        span.set_span(imp.brace_token.span.join());
100533d722a9Sopenharmony_ci        return Err(Error::new_spanned(span, "expected an empty impl block"));
100633d722a9Sopenharmony_ci    }
100733d722a9Sopenharmony_ci
100833d722a9Sopenharmony_ci    if let Some((bang, path, for_token)) = &imp.trait_ {
100933d722a9Sopenharmony_ci        let self_ty = &imp.self_ty;
101033d722a9Sopenharmony_ci        let span = quote!(#bang #path #for_token #self_ty);
101133d722a9Sopenharmony_ci        return Err(Error::new_spanned(
101233d722a9Sopenharmony_ci            span,
101333d722a9Sopenharmony_ci            "unexpected impl, expected something like `impl UniquePtr<T> {}`",
101433d722a9Sopenharmony_ci        ));
101533d722a9Sopenharmony_ci    }
101633d722a9Sopenharmony_ci
101733d722a9Sopenharmony_ci    if let Some(where_clause) = imp.generics.where_clause {
101833d722a9Sopenharmony_ci        return Err(Error::new_spanned(
101933d722a9Sopenharmony_ci            where_clause,
102033d722a9Sopenharmony_ci            "where-clause on an impl is not supported yet",
102133d722a9Sopenharmony_ci        ));
102233d722a9Sopenharmony_ci    }
102333d722a9Sopenharmony_ci    let mut impl_generics = Lifetimes {
102433d722a9Sopenharmony_ci        lt_token: imp.generics.lt_token,
102533d722a9Sopenharmony_ci        lifetimes: Punctuated::new(),
102633d722a9Sopenharmony_ci        gt_token: imp.generics.gt_token,
102733d722a9Sopenharmony_ci    };
102833d722a9Sopenharmony_ci    for pair in imp.generics.params.into_pairs() {
102933d722a9Sopenharmony_ci        let (param, punct) = pair.into_tuple();
103033d722a9Sopenharmony_ci        match param {
103133d722a9Sopenharmony_ci            GenericParam::Lifetime(def) if def.bounds.is_empty() => {
103233d722a9Sopenharmony_ci                impl_generics.lifetimes.push_value(def.lifetime);
103333d722a9Sopenharmony_ci                if let Some(punct) = punct {
103433d722a9Sopenharmony_ci                    impl_generics.lifetimes.push_punct(punct);
103533d722a9Sopenharmony_ci                }
103633d722a9Sopenharmony_ci            }
103733d722a9Sopenharmony_ci            _ => {
103833d722a9Sopenharmony_ci                let span = quote!(#impl_token #impl_generics);
103933d722a9Sopenharmony_ci                return Err(Error::new_spanned(
104033d722a9Sopenharmony_ci                    span,
104133d722a9Sopenharmony_ci                    "generic parameter on an impl is not supported yet",
104233d722a9Sopenharmony_ci                ));
104333d722a9Sopenharmony_ci            }
104433d722a9Sopenharmony_ci        }
104533d722a9Sopenharmony_ci    }
104633d722a9Sopenharmony_ci
104733d722a9Sopenharmony_ci    let mut negative_token = None;
104833d722a9Sopenharmony_ci    let mut self_ty = *imp.self_ty;
104933d722a9Sopenharmony_ci    if let RustType::Verbatim(ty) = &self_ty {
105033d722a9Sopenharmony_ci        let mut iter = ty.clone().into_iter();
105133d722a9Sopenharmony_ci        if let Some(TokenTree::Punct(punct)) = iter.next() {
105233d722a9Sopenharmony_ci            if punct.as_char() == '!' {
105333d722a9Sopenharmony_ci                let ty = iter.collect::<TokenStream>();
105433d722a9Sopenharmony_ci                if !ty.is_empty() {
105533d722a9Sopenharmony_ci                    negative_token = Some(Token![!](punct.span()));
105633d722a9Sopenharmony_ci                    self_ty = syn::parse2(ty)?;
105733d722a9Sopenharmony_ci                }
105833d722a9Sopenharmony_ci            }
105933d722a9Sopenharmony_ci        }
106033d722a9Sopenharmony_ci    }
106133d722a9Sopenharmony_ci
106233d722a9Sopenharmony_ci    let ty = parse_type(&self_ty)?;
106333d722a9Sopenharmony_ci    let ty_generics = match &ty {
106433d722a9Sopenharmony_ci        Type::RustBox(ty)
106533d722a9Sopenharmony_ci        | Type::RustVec(ty)
106633d722a9Sopenharmony_ci        | Type::UniquePtr(ty)
106733d722a9Sopenharmony_ci        | Type::SharedPtr(ty)
106833d722a9Sopenharmony_ci        | Type::WeakPtr(ty)
106933d722a9Sopenharmony_ci        | Type::CxxVector(ty) => match &ty.inner {
107033d722a9Sopenharmony_ci            Type::Ident(ident) => ident.generics.clone(),
107133d722a9Sopenharmony_ci            _ => Lifetimes::default(),
107233d722a9Sopenharmony_ci        },
107333d722a9Sopenharmony_ci        Type::Ident(_)
107433d722a9Sopenharmony_ci        | Type::Ref(_)
107533d722a9Sopenharmony_ci        | Type::Ptr(_)
107633d722a9Sopenharmony_ci        | Type::Str(_)
107733d722a9Sopenharmony_ci        | Type::Fn(_)
107833d722a9Sopenharmony_ci        | Type::Void(_)
107933d722a9Sopenharmony_ci        | Type::SliceRef(_)
108033d722a9Sopenharmony_ci        | Type::Array(_) => Lifetimes::default(),
108133d722a9Sopenharmony_ci    };
108233d722a9Sopenharmony_ci
108333d722a9Sopenharmony_ci    let negative = negative_token.is_some();
108433d722a9Sopenharmony_ci    let brace_token = imp.brace_token;
108533d722a9Sopenharmony_ci
108633d722a9Sopenharmony_ci    Ok(Api::Impl(Impl {
108733d722a9Sopenharmony_ci        cfg,
108833d722a9Sopenharmony_ci        impl_token,
108933d722a9Sopenharmony_ci        impl_generics,
109033d722a9Sopenharmony_ci        negative,
109133d722a9Sopenharmony_ci        ty,
109233d722a9Sopenharmony_ci        ty_generics,
109333d722a9Sopenharmony_ci        brace_token,
109433d722a9Sopenharmony_ci        negative_token,
109533d722a9Sopenharmony_ci    }))
109633d722a9Sopenharmony_ci}
109733d722a9Sopenharmony_ci
109833d722a9Sopenharmony_cifn parse_include(input: ParseStream) -> Result<Include> {
109933d722a9Sopenharmony_ci    if input.peek(LitStr) {
110033d722a9Sopenharmony_ci        let lit: LitStr = input.parse()?;
110133d722a9Sopenharmony_ci        let span = lit.span();
110233d722a9Sopenharmony_ci        return Ok(Include {
110333d722a9Sopenharmony_ci            cfg: CfgExpr::Unconditional,
110433d722a9Sopenharmony_ci            path: lit.value(),
110533d722a9Sopenharmony_ci            kind: IncludeKind::Quoted,
110633d722a9Sopenharmony_ci            begin_span: span,
110733d722a9Sopenharmony_ci            end_span: span,
110833d722a9Sopenharmony_ci        });
110933d722a9Sopenharmony_ci    }
111033d722a9Sopenharmony_ci
111133d722a9Sopenharmony_ci    if input.peek(Token![<]) {
111233d722a9Sopenharmony_ci        let mut path = String::new();
111333d722a9Sopenharmony_ci
111433d722a9Sopenharmony_ci        let langle: Token![<] = input.parse()?;
111533d722a9Sopenharmony_ci        while !input.is_empty() && !input.peek(Token![>]) {
111633d722a9Sopenharmony_ci            let token: TokenTree = input.parse()?;
111733d722a9Sopenharmony_ci            match token {
111833d722a9Sopenharmony_ci                TokenTree::Ident(token) => path += &token.to_string(),
111933d722a9Sopenharmony_ci                TokenTree::Literal(token)
112033d722a9Sopenharmony_ci                    if token
112133d722a9Sopenharmony_ci                        .to_string()
112233d722a9Sopenharmony_ci                        .starts_with(|ch: char| ch.is_ascii_digit()) =>
112333d722a9Sopenharmony_ci                {
112433d722a9Sopenharmony_ci                    path += &token.to_string();
112533d722a9Sopenharmony_ci                }
112633d722a9Sopenharmony_ci                TokenTree::Punct(token) => path.push(token.as_char()),
112733d722a9Sopenharmony_ci                _ => return Err(Error::new(token.span(), "unexpected token in include path")),
112833d722a9Sopenharmony_ci            }
112933d722a9Sopenharmony_ci        }
113033d722a9Sopenharmony_ci        let rangle: Token![>] = input.parse()?;
113133d722a9Sopenharmony_ci
113233d722a9Sopenharmony_ci        return Ok(Include {
113333d722a9Sopenharmony_ci            cfg: CfgExpr::Unconditional,
113433d722a9Sopenharmony_ci            path,
113533d722a9Sopenharmony_ci            kind: IncludeKind::Bracketed,
113633d722a9Sopenharmony_ci            begin_span: langle.span,
113733d722a9Sopenharmony_ci            end_span: rangle.span,
113833d722a9Sopenharmony_ci        });
113933d722a9Sopenharmony_ci    }
114033d722a9Sopenharmony_ci
114133d722a9Sopenharmony_ci    Err(input.error("expected \"quoted/path/to\" or <bracketed/path/to>"))
114233d722a9Sopenharmony_ci}
114333d722a9Sopenharmony_ci
114433d722a9Sopenharmony_cifn parse_type(ty: &RustType) -> Result<Type> {
114533d722a9Sopenharmony_ci    match ty {
114633d722a9Sopenharmony_ci        RustType::Reference(ty) => parse_type_reference(ty),
114733d722a9Sopenharmony_ci        RustType::Ptr(ty) => parse_type_ptr(ty),
114833d722a9Sopenharmony_ci        RustType::Path(ty) => parse_type_path(ty),
114933d722a9Sopenharmony_ci        RustType::Array(ty) => parse_type_array(ty),
115033d722a9Sopenharmony_ci        RustType::BareFn(ty) => parse_type_fn(ty),
115133d722a9Sopenharmony_ci        RustType::Tuple(ty) if ty.elems.is_empty() => Ok(Type::Void(ty.paren_token.span.join())),
115233d722a9Sopenharmony_ci        _ => Err(Error::new_spanned(ty, "unsupported type")),
115333d722a9Sopenharmony_ci    }
115433d722a9Sopenharmony_ci}
115533d722a9Sopenharmony_ci
115633d722a9Sopenharmony_cifn parse_type_reference(ty: &TypeReference) -> Result<Type> {
115733d722a9Sopenharmony_ci    let ampersand = ty.and_token;
115833d722a9Sopenharmony_ci    let lifetime = ty.lifetime.clone();
115933d722a9Sopenharmony_ci    let mutable = ty.mutability.is_some();
116033d722a9Sopenharmony_ci    let mutability = ty.mutability;
116133d722a9Sopenharmony_ci
116233d722a9Sopenharmony_ci    if let RustType::Slice(slice) = ty.elem.as_ref() {
116333d722a9Sopenharmony_ci        let inner = parse_type(&slice.elem)?;
116433d722a9Sopenharmony_ci        let bracket = slice.bracket_token;
116533d722a9Sopenharmony_ci        return Ok(Type::SliceRef(Box::new(SliceRef {
116633d722a9Sopenharmony_ci            ampersand,
116733d722a9Sopenharmony_ci            lifetime,
116833d722a9Sopenharmony_ci            mutable,
116933d722a9Sopenharmony_ci            bracket,
117033d722a9Sopenharmony_ci            inner,
117133d722a9Sopenharmony_ci            mutability,
117233d722a9Sopenharmony_ci        })));
117333d722a9Sopenharmony_ci    }
117433d722a9Sopenharmony_ci
117533d722a9Sopenharmony_ci    let inner = parse_type(&ty.elem)?;
117633d722a9Sopenharmony_ci    let pinned = false;
117733d722a9Sopenharmony_ci    let pin_tokens = None;
117833d722a9Sopenharmony_ci
117933d722a9Sopenharmony_ci    Ok(match &inner {
118033d722a9Sopenharmony_ci        Type::Ident(ident) if ident.rust == "str" => {
118133d722a9Sopenharmony_ci            if ty.mutability.is_some() {
118233d722a9Sopenharmony_ci                return Err(Error::new_spanned(ty, "unsupported type"));
118333d722a9Sopenharmony_ci            } else {
118433d722a9Sopenharmony_ci                Type::Str
118533d722a9Sopenharmony_ci            }
118633d722a9Sopenharmony_ci        }
118733d722a9Sopenharmony_ci        _ => Type::Ref,
118833d722a9Sopenharmony_ci    }(Box::new(Ref {
118933d722a9Sopenharmony_ci        pinned,
119033d722a9Sopenharmony_ci        ampersand,
119133d722a9Sopenharmony_ci        lifetime,
119233d722a9Sopenharmony_ci        mutable,
119333d722a9Sopenharmony_ci        inner,
119433d722a9Sopenharmony_ci        pin_tokens,
119533d722a9Sopenharmony_ci        mutability,
119633d722a9Sopenharmony_ci    })))
119733d722a9Sopenharmony_ci}
119833d722a9Sopenharmony_ci
119933d722a9Sopenharmony_cifn parse_type_ptr(ty: &TypePtr) -> Result<Type> {
120033d722a9Sopenharmony_ci    let star = ty.star_token;
120133d722a9Sopenharmony_ci    let mutable = ty.mutability.is_some();
120233d722a9Sopenharmony_ci    let constness = ty.const_token;
120333d722a9Sopenharmony_ci    let mutability = ty.mutability;
120433d722a9Sopenharmony_ci
120533d722a9Sopenharmony_ci    let inner = parse_type(&ty.elem)?;
120633d722a9Sopenharmony_ci
120733d722a9Sopenharmony_ci    Ok(Type::Ptr(Box::new(Ptr {
120833d722a9Sopenharmony_ci        star,
120933d722a9Sopenharmony_ci        mutable,
121033d722a9Sopenharmony_ci        inner,
121133d722a9Sopenharmony_ci        mutability,
121233d722a9Sopenharmony_ci        constness,
121333d722a9Sopenharmony_ci    })))
121433d722a9Sopenharmony_ci}
121533d722a9Sopenharmony_ci
121633d722a9Sopenharmony_cifn parse_type_path(ty: &TypePath) -> Result<Type> {
121733d722a9Sopenharmony_ci    let path = &ty.path;
121833d722a9Sopenharmony_ci    if ty.qself.is_none() && path.leading_colon.is_none() && path.segments.len() == 1 {
121933d722a9Sopenharmony_ci        let segment = &path.segments[0];
122033d722a9Sopenharmony_ci        let ident = segment.ident.clone();
122133d722a9Sopenharmony_ci        match &segment.arguments {
122233d722a9Sopenharmony_ci            PathArguments::None => return Ok(Type::Ident(NamedType::new(ident))),
122333d722a9Sopenharmony_ci            PathArguments::AngleBracketed(generic) => {
122433d722a9Sopenharmony_ci                if ident == "UniquePtr" && generic.args.len() == 1 {
122533d722a9Sopenharmony_ci                    if let GenericArgument::Type(arg) = &generic.args[0] {
122633d722a9Sopenharmony_ci                        let inner = parse_type(arg)?;
122733d722a9Sopenharmony_ci                        return Ok(Type::UniquePtr(Box::new(Ty1 {
122833d722a9Sopenharmony_ci                            name: ident,
122933d722a9Sopenharmony_ci                            langle: generic.lt_token,
123033d722a9Sopenharmony_ci                            inner,
123133d722a9Sopenharmony_ci                            rangle: generic.gt_token,
123233d722a9Sopenharmony_ci                        })));
123333d722a9Sopenharmony_ci                    }
123433d722a9Sopenharmony_ci                } else if ident == "SharedPtr" && generic.args.len() == 1 {
123533d722a9Sopenharmony_ci                    if let GenericArgument::Type(arg) = &generic.args[0] {
123633d722a9Sopenharmony_ci                        let inner = parse_type(arg)?;
123733d722a9Sopenharmony_ci                        return Ok(Type::SharedPtr(Box::new(Ty1 {
123833d722a9Sopenharmony_ci                            name: ident,
123933d722a9Sopenharmony_ci                            langle: generic.lt_token,
124033d722a9Sopenharmony_ci                            inner,
124133d722a9Sopenharmony_ci                            rangle: generic.gt_token,
124233d722a9Sopenharmony_ci                        })));
124333d722a9Sopenharmony_ci                    }
124433d722a9Sopenharmony_ci                } else if ident == "WeakPtr" && generic.args.len() == 1 {
124533d722a9Sopenharmony_ci                    if let GenericArgument::Type(arg) = &generic.args[0] {
124633d722a9Sopenharmony_ci                        let inner = parse_type(arg)?;
124733d722a9Sopenharmony_ci                        return Ok(Type::WeakPtr(Box::new(Ty1 {
124833d722a9Sopenharmony_ci                            name: ident,
124933d722a9Sopenharmony_ci                            langle: generic.lt_token,
125033d722a9Sopenharmony_ci                            inner,
125133d722a9Sopenharmony_ci                            rangle: generic.gt_token,
125233d722a9Sopenharmony_ci                        })));
125333d722a9Sopenharmony_ci                    }
125433d722a9Sopenharmony_ci                } else if ident == "CxxVector" && generic.args.len() == 1 {
125533d722a9Sopenharmony_ci                    if let GenericArgument::Type(arg) = &generic.args[0] {
125633d722a9Sopenharmony_ci                        let inner = parse_type(arg)?;
125733d722a9Sopenharmony_ci                        return Ok(Type::CxxVector(Box::new(Ty1 {
125833d722a9Sopenharmony_ci                            name: ident,
125933d722a9Sopenharmony_ci                            langle: generic.lt_token,
126033d722a9Sopenharmony_ci                            inner,
126133d722a9Sopenharmony_ci                            rangle: generic.gt_token,
126233d722a9Sopenharmony_ci                        })));
126333d722a9Sopenharmony_ci                    }
126433d722a9Sopenharmony_ci                } else if ident == "Box" && generic.args.len() == 1 {
126533d722a9Sopenharmony_ci                    if let GenericArgument::Type(arg) = &generic.args[0] {
126633d722a9Sopenharmony_ci                        let inner = parse_type(arg)?;
126733d722a9Sopenharmony_ci                        return Ok(Type::RustBox(Box::new(Ty1 {
126833d722a9Sopenharmony_ci                            name: ident,
126933d722a9Sopenharmony_ci                            langle: generic.lt_token,
127033d722a9Sopenharmony_ci                            inner,
127133d722a9Sopenharmony_ci                            rangle: generic.gt_token,
127233d722a9Sopenharmony_ci                        })));
127333d722a9Sopenharmony_ci                    }
127433d722a9Sopenharmony_ci                } else if ident == "Vec" && generic.args.len() == 1 {
127533d722a9Sopenharmony_ci                    if let GenericArgument::Type(arg) = &generic.args[0] {
127633d722a9Sopenharmony_ci                        let inner = parse_type(arg)?;
127733d722a9Sopenharmony_ci                        return Ok(Type::RustVec(Box::new(Ty1 {
127833d722a9Sopenharmony_ci                            name: ident,
127933d722a9Sopenharmony_ci                            langle: generic.lt_token,
128033d722a9Sopenharmony_ci                            inner,
128133d722a9Sopenharmony_ci                            rangle: generic.gt_token,
128233d722a9Sopenharmony_ci                        })));
128333d722a9Sopenharmony_ci                    }
128433d722a9Sopenharmony_ci                } else if ident == "Pin" && generic.args.len() == 1 {
128533d722a9Sopenharmony_ci                    if let GenericArgument::Type(arg) = &generic.args[0] {
128633d722a9Sopenharmony_ci                        let inner = parse_type(arg)?;
128733d722a9Sopenharmony_ci                        let pin_token = kw::Pin(ident.span());
128833d722a9Sopenharmony_ci                        if let Type::Ref(mut inner) = inner {
128933d722a9Sopenharmony_ci                            inner.pinned = true;
129033d722a9Sopenharmony_ci                            inner.pin_tokens =
129133d722a9Sopenharmony_ci                                Some((pin_token, generic.lt_token, generic.gt_token));
129233d722a9Sopenharmony_ci                            return Ok(Type::Ref(inner));
129333d722a9Sopenharmony_ci                        }
129433d722a9Sopenharmony_ci                    }
129533d722a9Sopenharmony_ci                } else {
129633d722a9Sopenharmony_ci                    let mut lifetimes = Punctuated::new();
129733d722a9Sopenharmony_ci                    let mut only_lifetimes = true;
129833d722a9Sopenharmony_ci                    for pair in generic.args.pairs() {
129933d722a9Sopenharmony_ci                        let (param, punct) = pair.into_tuple();
130033d722a9Sopenharmony_ci                        if let GenericArgument::Lifetime(param) = param {
130133d722a9Sopenharmony_ci                            lifetimes.push_value(param.clone());
130233d722a9Sopenharmony_ci                            if let Some(punct) = punct {
130333d722a9Sopenharmony_ci                                lifetimes.push_punct(*punct);
130433d722a9Sopenharmony_ci                            }
130533d722a9Sopenharmony_ci                        } else {
130633d722a9Sopenharmony_ci                            only_lifetimes = false;
130733d722a9Sopenharmony_ci                            break;
130833d722a9Sopenharmony_ci                        }
130933d722a9Sopenharmony_ci                    }
131033d722a9Sopenharmony_ci                    if only_lifetimes {
131133d722a9Sopenharmony_ci                        return Ok(Type::Ident(NamedType {
131233d722a9Sopenharmony_ci                            rust: ident,
131333d722a9Sopenharmony_ci                            generics: Lifetimes {
131433d722a9Sopenharmony_ci                                lt_token: Some(generic.lt_token),
131533d722a9Sopenharmony_ci                                lifetimes,
131633d722a9Sopenharmony_ci                                gt_token: Some(generic.gt_token),
131733d722a9Sopenharmony_ci                            },
131833d722a9Sopenharmony_ci                        }));
131933d722a9Sopenharmony_ci                    }
132033d722a9Sopenharmony_ci                }
132133d722a9Sopenharmony_ci            }
132233d722a9Sopenharmony_ci            PathArguments::Parenthesized(_) => {}
132333d722a9Sopenharmony_ci        }
132433d722a9Sopenharmony_ci    }
132533d722a9Sopenharmony_ci
132633d722a9Sopenharmony_ci    Err(Error::new_spanned(ty, "unsupported type"))
132733d722a9Sopenharmony_ci}
132833d722a9Sopenharmony_ci
132933d722a9Sopenharmony_cifn parse_type_array(ty: &TypeArray) -> Result<Type> {
133033d722a9Sopenharmony_ci    let inner = parse_type(&ty.elem)?;
133133d722a9Sopenharmony_ci
133233d722a9Sopenharmony_ci    let len_expr = if let Expr::Lit(lit) = &ty.len {
133333d722a9Sopenharmony_ci        lit
133433d722a9Sopenharmony_ci    } else {
133533d722a9Sopenharmony_ci        let msg = "unsupported expression, array length must be an integer literal";
133633d722a9Sopenharmony_ci        return Err(Error::new_spanned(&ty.len, msg));
133733d722a9Sopenharmony_ci    };
133833d722a9Sopenharmony_ci
133933d722a9Sopenharmony_ci    let len_token = if let Lit::Int(int) = &len_expr.lit {
134033d722a9Sopenharmony_ci        int.clone()
134133d722a9Sopenharmony_ci    } else {
134233d722a9Sopenharmony_ci        let msg = "array length must be an integer literal";
134333d722a9Sopenharmony_ci        return Err(Error::new_spanned(len_expr, msg));
134433d722a9Sopenharmony_ci    };
134533d722a9Sopenharmony_ci
134633d722a9Sopenharmony_ci    let len = len_token.base10_parse::<usize>()?;
134733d722a9Sopenharmony_ci    if len == 0 {
134833d722a9Sopenharmony_ci        let msg = "array with zero size is not supported";
134933d722a9Sopenharmony_ci        return Err(Error::new_spanned(ty, msg));
135033d722a9Sopenharmony_ci    }
135133d722a9Sopenharmony_ci
135233d722a9Sopenharmony_ci    let bracket = ty.bracket_token;
135333d722a9Sopenharmony_ci    let semi_token = ty.semi_token;
135433d722a9Sopenharmony_ci
135533d722a9Sopenharmony_ci    Ok(Type::Array(Box::new(Array {
135633d722a9Sopenharmony_ci        bracket,
135733d722a9Sopenharmony_ci        inner,
135833d722a9Sopenharmony_ci        semi_token,
135933d722a9Sopenharmony_ci        len,
136033d722a9Sopenharmony_ci        len_token,
136133d722a9Sopenharmony_ci    })))
136233d722a9Sopenharmony_ci}
136333d722a9Sopenharmony_ci
136433d722a9Sopenharmony_cifn parse_type_fn(ty: &TypeBareFn) -> Result<Type> {
136533d722a9Sopenharmony_ci    if ty.lifetimes.is_some() {
136633d722a9Sopenharmony_ci        return Err(Error::new_spanned(
136733d722a9Sopenharmony_ci            ty,
136833d722a9Sopenharmony_ci            "function pointer with lifetime parameters is not supported yet",
136933d722a9Sopenharmony_ci        ));
137033d722a9Sopenharmony_ci    }
137133d722a9Sopenharmony_ci
137233d722a9Sopenharmony_ci    if ty.variadic.is_some() {
137333d722a9Sopenharmony_ci        return Err(Error::new_spanned(
137433d722a9Sopenharmony_ci            ty,
137533d722a9Sopenharmony_ci            "variadic function pointer is not supported yet",
137633d722a9Sopenharmony_ci        ));
137733d722a9Sopenharmony_ci    }
137833d722a9Sopenharmony_ci
137933d722a9Sopenharmony_ci    let args = ty
138033d722a9Sopenharmony_ci        .inputs
138133d722a9Sopenharmony_ci        .iter()
138233d722a9Sopenharmony_ci        .enumerate()
138333d722a9Sopenharmony_ci        .map(|(i, arg)| {
138433d722a9Sopenharmony_ci            let (ident, colon_token) = match &arg.name {
138533d722a9Sopenharmony_ci                Some((ident, colon_token)) => (ident.clone(), *colon_token),
138633d722a9Sopenharmony_ci                None => {
138733d722a9Sopenharmony_ci                    let fn_span = ty.paren_token.span.join();
138833d722a9Sopenharmony_ci                    let ident = format_ident!("arg{}", i, span = fn_span);
138933d722a9Sopenharmony_ci                    let colon_token = Token![:](fn_span);
139033d722a9Sopenharmony_ci                    (ident, colon_token)
139133d722a9Sopenharmony_ci                }
139233d722a9Sopenharmony_ci            };
139333d722a9Sopenharmony_ci            let ty = parse_type(&arg.ty)?;
139433d722a9Sopenharmony_ci            let cfg = CfgExpr::Unconditional;
139533d722a9Sopenharmony_ci            let doc = Doc::new();
139633d722a9Sopenharmony_ci            let attrs = OtherAttrs::none();
139733d722a9Sopenharmony_ci            let visibility = Token![pub](ident.span());
139833d722a9Sopenharmony_ci            let name = pair(Namespace::default(), &ident, None, None);
139933d722a9Sopenharmony_ci            Ok(Var {
140033d722a9Sopenharmony_ci                cfg,
140133d722a9Sopenharmony_ci                doc,
140233d722a9Sopenharmony_ci                attrs,
140333d722a9Sopenharmony_ci                visibility,
140433d722a9Sopenharmony_ci                name,
140533d722a9Sopenharmony_ci                colon_token,
140633d722a9Sopenharmony_ci                ty,
140733d722a9Sopenharmony_ci            })
140833d722a9Sopenharmony_ci        })
140933d722a9Sopenharmony_ci        .collect::<Result<_>>()?;
141033d722a9Sopenharmony_ci
141133d722a9Sopenharmony_ci    let mut throws_tokens = None;
141233d722a9Sopenharmony_ci    let ret = parse_return_type(&ty.output, &mut throws_tokens)?;
141333d722a9Sopenharmony_ci    let throws = throws_tokens.is_some();
141433d722a9Sopenharmony_ci
141533d722a9Sopenharmony_ci    let asyncness = None;
141633d722a9Sopenharmony_ci    let unsafety = ty.unsafety;
141733d722a9Sopenharmony_ci    let fn_token = ty.fn_token;
141833d722a9Sopenharmony_ci    let generics = Generics::default();
141933d722a9Sopenharmony_ci    let receiver = None;
142033d722a9Sopenharmony_ci    let paren_token = ty.paren_token;
142133d722a9Sopenharmony_ci
142233d722a9Sopenharmony_ci    Ok(Type::Fn(Box::new(Signature {
142333d722a9Sopenharmony_ci        asyncness,
142433d722a9Sopenharmony_ci        unsafety,
142533d722a9Sopenharmony_ci        fn_token,
142633d722a9Sopenharmony_ci        generics,
142733d722a9Sopenharmony_ci        receiver,
142833d722a9Sopenharmony_ci        args,
142933d722a9Sopenharmony_ci        ret,
143033d722a9Sopenharmony_ci        throws,
143133d722a9Sopenharmony_ci        paren_token,
143233d722a9Sopenharmony_ci        throws_tokens,
143333d722a9Sopenharmony_ci    })))
143433d722a9Sopenharmony_ci}
143533d722a9Sopenharmony_ci
143633d722a9Sopenharmony_cifn parse_return_type(
143733d722a9Sopenharmony_ci    ty: &ReturnType,
143833d722a9Sopenharmony_ci    throws_tokens: &mut Option<(kw::Result, Token![<], Token![>])>,
143933d722a9Sopenharmony_ci) -> Result<Option<Type>> {
144033d722a9Sopenharmony_ci    let mut ret = match ty {
144133d722a9Sopenharmony_ci        ReturnType::Default => return Ok(None),
144233d722a9Sopenharmony_ci        ReturnType::Type(_, ret) => ret.as_ref(),
144333d722a9Sopenharmony_ci    };
144433d722a9Sopenharmony_ci
144533d722a9Sopenharmony_ci    if let RustType::Path(ty) = ret {
144633d722a9Sopenharmony_ci        let path = &ty.path;
144733d722a9Sopenharmony_ci        if ty.qself.is_none() && path.leading_colon.is_none() && path.segments.len() == 1 {
144833d722a9Sopenharmony_ci            let segment = &path.segments[0];
144933d722a9Sopenharmony_ci            let ident = segment.ident.clone();
145033d722a9Sopenharmony_ci            if let PathArguments::AngleBracketed(generic) = &segment.arguments {
145133d722a9Sopenharmony_ci                if ident == "Result" && generic.args.len() == 1 {
145233d722a9Sopenharmony_ci                    if let GenericArgument::Type(arg) = &generic.args[0] {
145333d722a9Sopenharmony_ci                        ret = arg;
145433d722a9Sopenharmony_ci                        *throws_tokens =
145533d722a9Sopenharmony_ci                            Some((kw::Result(ident.span()), generic.lt_token, generic.gt_token));
145633d722a9Sopenharmony_ci                    }
145733d722a9Sopenharmony_ci                }
145833d722a9Sopenharmony_ci            }
145933d722a9Sopenharmony_ci        }
146033d722a9Sopenharmony_ci    }
146133d722a9Sopenharmony_ci
146233d722a9Sopenharmony_ci    match parse_type(ret)? {
146333d722a9Sopenharmony_ci        Type::Void(_) => Ok(None),
146433d722a9Sopenharmony_ci        ty => Ok(Some(ty)),
146533d722a9Sopenharmony_ci    }
146633d722a9Sopenharmony_ci}
146733d722a9Sopenharmony_ci
146833d722a9Sopenharmony_cifn visibility_pub(vis: &Visibility, inherited: Span) -> Token![pub] {
146933d722a9Sopenharmony_ci    Token![pub](match vis {
147033d722a9Sopenharmony_ci        Visibility::Public(vis) => vis.span,
147133d722a9Sopenharmony_ci        Visibility::Restricted(vis) => vis.pub_token.span,
147233d722a9Sopenharmony_ci        Visibility::Inherited => inherited,
147333d722a9Sopenharmony_ci    })
147433d722a9Sopenharmony_ci}
147533d722a9Sopenharmony_ci
147633d722a9Sopenharmony_cifn pair(
147733d722a9Sopenharmony_ci    namespace: Namespace,
147833d722a9Sopenharmony_ci    default: &Ident,
147933d722a9Sopenharmony_ci    cxx: Option<ForeignName>,
148033d722a9Sopenharmony_ci    rust: Option<Ident>,
148133d722a9Sopenharmony_ci) -> Pair {
148233d722a9Sopenharmony_ci    Pair {
148333d722a9Sopenharmony_ci        namespace,
148433d722a9Sopenharmony_ci        cxx: cxx
148533d722a9Sopenharmony_ci            .unwrap_or_else(|| ForeignName::parse(&default.to_string(), default.span()).unwrap()),
148633d722a9Sopenharmony_ci        rust: rust.unwrap_or_else(|| default.clone()),
148733d722a9Sopenharmony_ci    }
148833d722a9Sopenharmony_ci}
1489