aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Tolnay <dtolnay@gmail.com>2020-12-28 22:04:10 -0800
committerDavid Tolnay <dtolnay@gmail.com>2020-12-28 22:12:28 -0800
commitee3123241fbc49912ce79da024271d21eba9237c (patch)
tree458e6fb5fba069ea2fecf2420493d2a08413e0bb
parent0c8cb95a3c5aa964a7c33fce07ab7e11882d2160 (diff)
downloadcxx-ee3123241fbc49912ce79da024271d21eba9237c.tar.gz
Store additional token information with extern type lifetimes
-rw-r--r--gen/src/nested.rs9
-rw-r--r--syntax/check.rs4
-rw-r--r--syntax/mod.rs10
-rw-r--r--syntax/parse.rs39
4 files changed, 43 insertions, 19 deletions
diff --git a/gen/src/nested.rs b/gen/src/nested.rs
index 99cfdf8f..66d854e5 100644
--- a/gen/src/nested.rs
+++ b/gen/src/nested.rs
@@ -52,9 +52,10 @@ fn sort_by_inner_namespace(apis: Vec<&Api>, depth: usize) -> NamespaceEntries {
mod tests {
use super::NamespaceEntries;
use crate::syntax::namespace::Namespace;
- use crate::syntax::{Api, Doc, ExternType, Lang, Pair};
+ use crate::syntax::{Api, Doc, ExternType, Lang, Lifetimes, Pair};
use proc_macro2::{Ident, Span};
use std::iter::FromIterator;
+ use syn::punctuated::Punctuated;
use syn::Token;
#[test]
@@ -136,7 +137,11 @@ mod tests {
cxx: ident.clone(),
rust: ident,
},
- lifetimes: Vec::new(),
+ generics: Lifetimes {
+ lt_token: None,
+ lifetimes: Punctuated::new(),
+ gt_token: None,
+ },
colon_token: None,
bounds: Vec::new(),
semi_token: Token![;](Span::call_site()),
diff --git a/syntax/check.rs b/syntax/check.rs
index 29013cb2..fcd5f9a5 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -337,7 +337,7 @@ fn check_api_type(cx: &mut Check, ety: &ExternType) {
cx.error(derive, msg);
}
- if let Some(lifetime) = ety.lifetimes.first() {
+ if let Some(lifetime) = ety.generics.lifetimes.first() {
cx.error(lifetime, "extern type with lifetimes is not supported yet");
}
@@ -445,7 +445,7 @@ fn check_api_type_alias(cx: &mut Check, alias: &TypeAlias) {
cx.error(derive, msg);
}
- if let Some(lifetime) = alias.lifetimes.first() {
+ if let Some(lifetime) = alias.generics.lifetimes.first() {
cx.error(lifetime, "extern type with lifetimes is not supported yet");
}
}
diff --git a/syntax/mod.rs b/syntax/mod.rs
index c878ae28..009afee8 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -74,7 +74,7 @@ pub struct ExternType {
pub derives: Vec<Derive>,
pub type_token: Token![type],
pub name: Pair,
- pub lifetimes: Vec<Lifetime>,
+ pub generics: Lifetimes,
pub colon_token: Option<Token![:]>,
pub bounds: Vec<Derive>,
pub semi_token: Token![;],
@@ -116,7 +116,7 @@ pub struct TypeAlias {
pub derives: Vec<Derive>,
pub type_token: Token![type],
pub name: Pair,
- pub lifetimes: Vec<Lifetime>,
+ pub generics: Lifetimes,
pub eq_token: Token![=],
pub ty: RustType,
pub semi_token: Token![;],
@@ -130,6 +130,12 @@ pub struct Impl {
pub negative_token: Option<Token![!]>,
}
+pub struct Lifetimes {
+ pub lt_token: Option<Token![<]>,
+ pub lifetimes: Punctuated<Lifetime, Token![,]>,
+ pub gt_token: Option<Token![>]>,
+}
+
pub struct Signature {
pub unsafety: Option<Token![unsafe]>,
pub fn_token: Token![fn],
diff --git a/syntax/parse.rs b/syntax/parse.rs
index 65e07aaa..bb5ac7bd 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -4,8 +4,8 @@ use crate::syntax::report::Errors;
use crate::syntax::Atom::*;
use crate::syntax::{
attrs, error, Api, Array, Derive, Doc, Enum, ExternFn, ExternType, Impl, Include, IncludeKind,
- Lang, Namespace, Pair, Receiver, Ref, RustName, Signature, SliceRef, Struct, Ty1, Type,
- TypeAlias, Var, Variant,
+ Lang, Lifetimes, Namespace, Pair, Receiver, Ref, RustName, Signature, SliceRef, Struct, Ty1,
+ Type, TypeAlias, Var, Variant,
};
use proc_macro2::{Delimiter, Group, Span, TokenStream, TokenTree};
use quote::{format_ident, quote, quote_spanned};
@@ -13,8 +13,8 @@ use syn::parse::{ParseStream, Parser};
use syn::punctuated::Punctuated;
use syn::{
Abi, Attribute, Error, Expr, Fields, FnArg, ForeignItem, ForeignItemFn, ForeignItemType,
- GenericArgument, GenericParam, Generics, Ident, ItemEnum, ItemImpl, ItemStruct, Lifetime, Lit,
- LitStr, Pat, PathArguments, Result, ReturnType, Token, TraitBound, TraitBoundModifier,
+ GenericArgument, GenericParam, Generics, Ident, ItemEnum, ItemImpl, ItemStruct, Lit, LitStr,
+ Pat, PathArguments, Result, ReturnType, Token, TraitBound, TraitBoundModifier,
Type as RustType, TypeArray, TypeBareFn, TypeParamBound, TypePath, TypeReference,
Variant as RustVariant,
};
@@ -385,7 +385,11 @@ fn parse_extern_type(
let type_token = foreign_type.type_token;
let name = pair(namespace, &foreign_type.ident, cxx_name, rust_name);
- let lifetimes = Vec::new();
+ let generics = Lifetimes {
+ lt_token: None,
+ lifetimes: Punctuated::new(),
+ gt_token: None,
+ };
let colon_token = None;
let bounds = Vec::new();
let semi_token = foreign_type.semi_token;
@@ -399,7 +403,7 @@ fn parse_extern_type(
derives,
type_token,
name,
- lifetimes,
+ generics,
colon_token,
bounds,
semi_token,
@@ -581,9 +585,10 @@ fn parse_extern_verbatim(
};
let ident: Ident = input.parse()?;
let generics: Generics = input.parse()?;
- let mut lifetimes = Vec::new();
+ let mut lifetimes = Punctuated::new();
let mut has_unsupported_generic_param = false;
- for param in generics.params {
+ for pair in generics.params.into_pairs() {
+ let (param, punct) = pair.into_tuple();
match param {
GenericParam::Lifetime(param) => {
if !param.bounds.is_empty() && !has_unsupported_generic_param {
@@ -591,7 +596,10 @@ fn parse_extern_verbatim(
cx.error(&param, msg);
has_unsupported_generic_param = true;
}
- lifetimes.push(param.lifetime);
+ lifetimes.push_value(param.lifetime);
+ if let Some(punct) = punct {
+ lifetimes.push_punct(punct);
+ }
}
GenericParam::Type(param) => {
if !has_unsupported_generic_param {
@@ -609,6 +617,11 @@ fn parse_extern_verbatim(
}
}
}
+ let 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;
@@ -632,7 +645,7 @@ fn parse_type_alias(
attrs: Vec<Attribute>,
type_token: Token![type],
ident: Ident,
- lifetimes: Vec<Lifetime>,
+ generics: Lifetimes,
input: ParseStream,
lang: Lang,
namespace: &Namespace,
@@ -672,7 +685,7 @@ fn parse_type_alias(
derives,
type_token,
name,
- lifetimes,
+ generics,
eq_token,
ty,
semi_token,
@@ -684,7 +697,7 @@ fn parse_extern_type_bounded(
attrs: Vec<Attribute>,
type_token: Token![type],
ident: Ident,
- lifetimes: Vec<Lifetime>,
+ generics: Lifetimes,
input: ParseStream,
lang: Lang,
trusted: bool,
@@ -752,7 +765,7 @@ fn parse_extern_type_bounded(
derives,
type_token,
name,
- lifetimes,
+ generics,
colon_token,
bounds,
semi_token,