diff options
author | David Tolnay <dtolnay@gmail.com> | 2020-12-28 22:04:10 -0800 |
---|---|---|
committer | David Tolnay <dtolnay@gmail.com> | 2020-12-28 22:12:28 -0800 |
commit | ee3123241fbc49912ce79da024271d21eba9237c (patch) | |
tree | 458e6fb5fba069ea2fecf2420493d2a08413e0bb | |
parent | 0c8cb95a3c5aa964a7c33fce07ab7e11882d2160 (diff) | |
download | cxx-ee3123241fbc49912ce79da024271d21eba9237c.tar.gz |
Store additional token information with extern type lifetimes
-rw-r--r-- | gen/src/nested.rs | 9 | ||||
-rw-r--r-- | syntax/check.rs | 4 | ||||
-rw-r--r-- | syntax/mod.rs | 10 | ||||
-rw-r--r-- | syntax/parse.rs | 39 |
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(¶m, 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, |