aboutsummaryrefslogtreecommitdiff
path: root/syntax/parse.rs
diff options
context:
space:
mode:
Diffstat (limited to 'syntax/parse.rs')
-rw-r--r--syntax/parse.rs172
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,
})