///
/// *This type is available only if Syn is built with the `"derive"` or `"full"`
/// feature.*
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub struct Generics {
pub lt_token: Option<Token![<]>,
pub params: Punctuated<GenericParam, Token![,]>,
///
/// This type is a [syntax tree enum].
///
- /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
+ /// [syntax tree enum]: Expr#syntax-tree-enums
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub enum GenericParam {
/// A generic type parameter: `T: Into<String>`.
Type(TypeParam),
///
/// *This type is available only if Syn is built with the `"derive"` or
/// `"full"` feature.*
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub struct TypeParam {
pub attrs: Vec<Attribute>,
pub ident: Ident,
///
/// *This type is available only if Syn is built with the `"derive"` or
/// `"full"` feature.*
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub struct LifetimeDef {
pub attrs: Vec<Attribute>,
pub lifetime: Lifetime,
///
/// *This type is available only if Syn is built with the `"derive"` or
/// `"full"` feature.*
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub struct ConstParam {
pub attrs: Vec<Attribute>,
pub const_token: Token![const],
/// Initializes an empty `where`-clause if there is not one present already.
pub fn make_where_clause(&mut self) -> &mut WhereClause {
- // This is Option::get_or_insert_with in Rust 1.20.
- if self.where_clause.is_none() {
- self.where_clause = Some(WhereClause {
- where_token: <Token![where]>::default(),
- predicates: Punctuated::new(),
- });
- }
- match &mut self.where_clause {
- Some(where_clause) => where_clause,
- None => unreachable!(),
- }
+ self.where_clause.get_or_insert_with(|| WhereClause {
+ where_token: <Token![where]>::default(),
+ predicates: Punctuated::new(),
+ })
}
}
/// *This type is available only if Syn is built with the `"derive"` or `"full"`
/// feature and the `"printing"` feature.*
#[cfg(feature = "printing")]
+#[cfg_attr(
+ doc_cfg,
+ doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
+)]
pub struct ImplGenerics<'a>(&'a Generics);
/// Returned by `Generics::split_for_impl`.
/// *This type is available only if Syn is built with the `"derive"` or `"full"`
/// feature and the `"printing"` feature.*
#[cfg(feature = "printing")]
+#[cfg_attr(
+ doc_cfg,
+ doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
+)]
pub struct TypeGenerics<'a>(&'a Generics);
/// Returned by `TypeGenerics::as_turbofish`.
/// *This type is available only if Syn is built with the `"derive"` or `"full"`
/// feature and the `"printing"` feature.*
#[cfg(feature = "printing")]
+#[cfg_attr(
+ doc_cfg,
+ doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
+)]
pub struct Turbofish<'a>(&'a Generics);
#[cfg(feature = "printing")]
///
/// *This method is available only if Syn is built with the `"derive"` or
/// `"full"` feature and the `"printing"` feature.*
+ #[cfg_attr(
+ doc_cfg,
+ doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
+ )]
pub fn split_for_impl(&self) -> (ImplGenerics, TypeGenerics, Option<&WhereClause>) {
(
ImplGenerics(self),
macro_rules! generics_wrapper_impls {
($ty:ident) => {
#[cfg(feature = "clone-impls")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
impl<'a> Clone for $ty<'a> {
fn clone(&self) -> Self {
$ty(self.0)
}
#[cfg(feature = "extra-traits")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
impl<'a> Debug for $ty<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
}
#[cfg(feature = "extra-traits")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
impl<'a> Eq for $ty<'a> {}
#[cfg(feature = "extra-traits")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
impl<'a> PartialEq for $ty<'a> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
#[cfg(feature = "extra-traits")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
impl<'a> Hash for $ty<'a> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state);
///
/// *This type is available only if Syn is built with the `"derive"` or `"full"`
/// feature.*
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub struct BoundLifetimes {
pub for_token: Token![for],
pub lt_token: Token![<],
///
/// *This type is available only if Syn is built with the `"derive"` or `"full"`
/// feature.*
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub enum TypeParamBound {
Trait(TraitBound),
Lifetime(Lifetime),
///
/// *This type is available only if Syn is built with the `"derive"` or `"full"`
/// feature.*
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub struct TraitBound {
pub paren_token: Option<token::Paren>,
pub modifier: TraitBoundModifier,
///
/// *This type is available only if Syn is built with the `"derive"` or `"full"`
/// feature.*
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub enum TraitBoundModifier {
None,
Maybe(Token![?]),
///
/// *This type is available only if Syn is built with the `"derive"` or `"full"`
/// feature.*
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub struct WhereClause {
pub where_token: Token![where],
pub predicates: Punctuated<WherePredicate, Token![,]>,
///
/// This type is a [syntax tree enum].
///
- /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
+ /// [syntax tree enum]: Expr#syntax-tree-enums
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub enum WherePredicate {
/// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
Type(PredicateType),
///
/// *This type is available only if Syn is built with the `"derive"` or
/// `"full"` feature.*
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub struct PredicateType {
/// Any lifetimes from a `for` binding
pub lifetimes: Option<BoundLifetimes>,
///
/// *This type is available only if Syn is built with the `"derive"` or
/// `"full"` feature.*
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub struct PredicateLifetime {
pub lifetime: Lifetime,
pub colon_token: Token![:],
///
/// *This type is available only if Syn is built with the `"derive"` or
/// `"full"` feature.*
+ #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
pub struct PredicateEq {
pub lhs_ty: Type,
pub eq_token: Token![=],
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
+ use crate::ext::IdentExt;
use crate::parse::{Parse, ParseStream, Result};
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for Generics {
fn parse(input: ParseStream) -> Result<Self> {
if !input.peek(Token![<]) {
let lt_token: Token![<] = input.parse()?;
let mut params = Punctuated::new();
- let mut allow_lifetime_param = true;
loop {
if input.peek(Token![>]) {
break;
let attrs = input.call(Attribute::parse_outer)?;
let lookahead = input.lookahead1();
- if allow_lifetime_param && lookahead.peek(Lifetime) {
+ if lookahead.peek(Lifetime) {
params.push_value(GenericParam::Lifetime(LifetimeDef {
attrs,
..input.parse()?
}));
} else if lookahead.peek(Ident) {
- allow_lifetime_param = false;
params.push_value(GenericParam::Type(TypeParam {
attrs,
..input.parse()?
}));
} else if lookahead.peek(Token![const]) {
- allow_lifetime_param = false;
params.push_value(GenericParam::Const(ConstParam {
attrs,
..input.parse()?
}));
+ } else if input.peek(Token![_]) {
+ params.push_value(GenericParam::Type(TypeParam {
+ attrs,
+ ident: input.call(Ident::parse_any)?,
+ colon_token: None,
+ bounds: Punctuated::new(),
+ eq_token: None,
+ default: None,
+ }));
} else {
return Err(lookahead.error());
}
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for GenericParam {
fn parse(input: ParseStream) -> Result<Self> {
let attrs = input.call(Attribute::parse_outer)?;
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for LifetimeDef {
fn parse(input: ParseStream) -> Result<Self> {
let has_colon;
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for BoundLifetimes {
fn parse(input: ParseStream) -> Result<Self> {
Ok(BoundLifetimes {
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for Option<BoundLifetimes> {
fn parse(input: ParseStream) -> Result<Self> {
if input.peek(Token![for]) {
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for TypeParam {
fn parse(input: ParseStream) -> Result<Self> {
let attrs = input.call(Attribute::parse_outer)?;
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for TypeParamBound {
fn parse(input: ParseStream) -> Result<Self> {
if input.peek(Lifetime) {
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for TraitBound {
fn parse(input: ParseStream) -> Result<Self> {
let modifier: TraitBoundModifier = input.parse()?;
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for TraitBoundModifier {
fn parse(input: ParseStream) -> Result<Self> {
if input.peek(Token![?]) {
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for ConstParam {
fn parse(input: ParseStream) -> Result<Self> {
let mut default = None;
eq_token: {
if input.peek(Token![=]) {
let eq_token = input.parse()?;
- default = Some(input.parse::<Expr>()?);
+ default = Some(path::parsing::const_argument(input)?);
Some(eq_token)
} else {
None
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for WhereClause {
fn parse(input: ParseStream) -> Result<Self> {
Ok(WhereClause {
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for Option<WhereClause> {
fn parse(input: ParseStream) -> Result<Self> {
if input.peek(Token![where]) {
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for WherePredicate {
fn parse(input: ParseStream) -> Result<Self> {
if input.peek(Lifetime) && input.peek2(Token![:]) {
use proc_macro2::TokenTree;
use quote::{ToTokens, TokenStreamExt};
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
impl ToTokens for Generics {
fn to_tokens(&self, tokens: &mut TokenStream) {
if self.params.is_empty() {
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
impl ToTokens for BoundLifetimes {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.for_token.to_tokens(tokens);
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
impl ToTokens for LifetimeDef {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
impl ToTokens for TypeParam {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
{
if self.eq_token.is_none() {
if let Type::Verbatim(default) = default {
- let mut iter = default.clone().into_iter();
- match (iter.next(), iter.next()) {
- (Some(TokenTree::Punct(ref q)), Some(TokenTree::Ident(ref c)))
- if q.as_char() == '?' && c == "const" =>
- {
- return default.to_tokens(tokens);
+ let mut iter = default.clone().into_iter().peekable();
+ while let Some(token) = iter.next() {
+ if let TokenTree::Punct(q) = token {
+ if q.as_char() == '?' {
+ if let Some(TokenTree::Ident(c)) = iter.peek() {
+ if c == "const" {
+ if self.bounds.is_empty() {
+ TokensOrDefault(&self.colon_token)
+ .to_tokens(tokens);
+ }
+ return default.to_tokens(tokens);
+ }
+ }
+ }
}
- _ => {}
}
}
}
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
impl ToTokens for TraitBound {
fn to_tokens(&self, tokens: &mut TokenStream) {
let to_tokens = |tokens: &mut TokenStream| {
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
impl ToTokens for TraitBoundModifier {
fn to_tokens(&self, tokens: &mut TokenStream) {
match self {
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
impl ToTokens for ConstParam {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
impl ToTokens for WhereClause {
fn to_tokens(&self, tokens: &mut TokenStream) {
if !self.predicates.is_empty() {
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
impl ToTokens for PredicateType {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.lifetimes.to_tokens(tokens);
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
impl ToTokens for PredicateLifetime {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.lifetime.to_tokens(tokens);
}
}
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
impl ToTokens for PredicateEq {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.lhs_ty.to_tokens(tokens);