diff options
Diffstat (limited to 'syntax/parse.rs')
-rw-r--r-- | syntax/parse.rs | 172 |
1 files changed, 84 insertions, 88 deletions
diff --git a/syntax/parse.rs b/syntax/parse.rs index 1754c600..c6fee5f8 100644 --- a/syntax/parse.rs +++ b/syntax/parse.rs @@ -489,11 +489,7 @@ fn parse_extern_type( let type_token = foreign_type.type_token; let visibility = visibility_pub(&foreign_type.vis, type_token.span); let name = pair(namespace, &foreign_type.ident, cxx_name, rust_name); - let generics = Lifetimes { - lt_token: None, - lifetimes: Punctuated::new(), - gt_token: None, - }; + let generics = extern_type_lifetimes(cx, foreign_type.generics); let colon_token = None; let bounds = Vec::new(); let semi_token = foreign_type.semi_token; @@ -611,7 +607,27 @@ fn parse_extern_fn( }); continue; } - return Err(Error::new_spanned(arg, "unsupported signature")); + if let Some(colon_token) = arg.colon_token { + let ty = parse_type(&arg.ty)?; + if let Type::Ref(reference) = ty { + if let Type::Ident(ident) = reference.inner { + receiver = Some(Receiver { + pinned: reference.pinned, + ampersand: reference.ampersand, + lifetime: reference.lifetime, + mutable: reference.mutable, + var: Token![self](ident.rust.span()), + colon_token, + ty: ident, + shorthand: false, + pin_tokens: reference.pin_tokens, + mutability: reference.mutability, + }); + continue; + } + } + } + return Err(Error::new_spanned(arg, "unsupported method receiver")); } FnArg::Typed(arg) => { let ident = match arg.pat.as_ref() { @@ -622,45 +638,24 @@ fn parse_extern_fn( _ => return Err(Error::new_spanned(arg, "unsupported signature")), }; let ty = parse_type(&arg.ty)?; - if ident != "self" { - let cfg = CfgExpr::Unconditional; - let doc = Doc::new(); - let attrs = OtherAttrs::none(); - let visibility = Token![pub](ident.span()); - let name = pair(Namespace::default(), &ident, None, None); - let colon_token = arg.colon_token; - args.push_value(Var { - cfg, - doc, - attrs, - visibility, - name, - colon_token, - ty, - }); - if let Some(comma) = comma { - args.push_punct(*comma); - } - continue; - } - if let Type::Ref(reference) = ty { - if let Type::Ident(ident) = reference.inner { - receiver = Some(Receiver { - pinned: reference.pinned, - ampersand: reference.ampersand, - lifetime: reference.lifetime, - mutable: reference.mutable, - var: Token![self](ident.rust.span()), - colon_token: arg.colon_token, - ty: ident, - shorthand: false, - pin_tokens: reference.pin_tokens, - mutability: reference.mutability, - }); - continue; - } + let cfg = CfgExpr::Unconditional; + let doc = Doc::new(); + let attrs = OtherAttrs::none(); + let visibility = Token![pub](ident.span()); + let name = pair(Namespace::default(), &ident, None, None); + let colon_token = arg.colon_token; + args.push_value(Var { + cfg, + doc, + attrs, + visibility, + name, + colon_token, + ty, + }); + if let Some(comma) = comma { + args.push_punct(*comma); } - return Err(Error::new_spanned(arg, "unsupported method receiver")); } } } @@ -756,6 +751,45 @@ fn parse_extern_verbatim_type( let type_token: Token![type] = input.parse()?; let ident: Ident = input.parse()?; let generics: Generics = input.parse()?; + let lifetimes = extern_type_lifetimes(cx, generics); + let lookahead = input.lookahead1(); + if lookahead.peek(Token![=]) { + // type Alias = crate::path::to::Type; + parse_type_alias( + cx, + unparsed_attrs, + visibility, + type_token, + ident, + lifetimes, + input, + lang, + extern_block_cfg, + namespace, + attrs, + ) + } else if lookahead.peek(Token![:]) { + // type Opaque: Bound2 + Bound2; + parse_extern_type_bounded( + cx, + unparsed_attrs, + visibility, + type_token, + ident, + lifetimes, + input, + lang, + trusted, + extern_block_cfg, + namespace, + attrs, + ) + } else { + Err(lookahead.error()) + } +} + +fn extern_type_lifetimes(cx: &mut Errors, generics: Generics) -> Lifetimes { let mut lifetimes = Punctuated::new(); let mut has_unsupported_generic_param = false; for pair in generics.params.into_pairs() { @@ -788,45 +822,10 @@ fn parse_extern_verbatim_type( } } } - let lifetimes = Lifetimes { + Lifetimes { lt_token: generics.lt_token, lifetimes, gt_token: generics.gt_token, - }; - let lookahead = input.lookahead1(); - if lookahead.peek(Token![=]) { - // type Alias = crate::path::to::Type; - parse_type_alias( - cx, - unparsed_attrs, - visibility, - type_token, - ident, - lifetimes, - input, - lang, - extern_block_cfg, - namespace, - attrs, - ) - } else if lookahead.peek(Token![:]) || lookahead.peek(Token![;]) { - // type Opaque: Bound2 + Bound2; - parse_extern_type_bounded( - cx, - unparsed_attrs, - visibility, - type_token, - ident, - lifetimes, - input, - lang, - trusted, - extern_block_cfg, - namespace, - attrs, - ) - } else { - Err(lookahead.error()) } } @@ -928,9 +927,7 @@ fn parse_extern_type_bounded( } else { false } => {} - bound @ TypeParamBound::Trait(_) | bound @ TypeParamBound::Lifetime(_) => { - cx.error(bound, "unsupported trait"); - } + bound => cx.error(bound, "unsupported trait"), } let lookahead = input.lookahead1(); @@ -1004,7 +1001,7 @@ fn parse_impl(cx: &mut Errors, imp: ItemImpl) -> Result<Api> { if !imp.items.is_empty() { let mut span = Group::new(Delimiter::Brace, TokenStream::new()); - span.set_span(imp.brace_token.span); + span.set_span(imp.brace_token.span.join()); return Err(Error::new_spanned(span, "expected an empty impl block")); } @@ -1151,7 +1148,7 @@ fn parse_type(ty: &RustType) -> Result<Type> { RustType::Path(ty) => parse_type_path(ty), RustType::Array(ty) => parse_type_array(ty), RustType::BareFn(ty) => parse_type_fn(ty), - RustType::Tuple(ty) if ty.elems.is_empty() => Ok(Type::Void(ty.paren_token.span)), + RustType::Tuple(ty) if ty.elems.is_empty() => Ok(Type::Void(ty.paren_token.span.join())), _ => Err(Error::new_spanned(ty, "unsupported type")), } } @@ -1387,7 +1384,7 @@ fn parse_type_fn(ty: &TypeBareFn) -> Result<Type> { let (ident, colon_token) = match &arg.name { Some((ident, colon_token)) => (ident.clone(), *colon_token), None => { - let fn_span = ty.paren_token.span; + let fn_span = ty.paren_token.span.join(); let ident = format_ident!("arg{}", i, span = fn_span); let colon_token = Token![:](fn_span); (ident, colon_token) @@ -1470,8 +1467,7 @@ fn parse_return_type( fn visibility_pub(vis: &Visibility, inherited: Span) -> Token![pub] { Token![pub](match vis { - Visibility::Public(vis) => vis.pub_token.span, - Visibility::Crate(vis) => vis.crate_token.span, + Visibility::Public(vis) => vis.span, Visibility::Restricted(vis) => vis.pub_token.span, Visibility::Inherited => inherited, }) |