use super::*;
use crate::punctuated::Punctuated;
use proc_macro2::TokenStream;
ast_enum_of_structs! {
    
    
    
    
    
    
    
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub enum Pat {
        
        Box(PatBox),
        
        Ident(PatIdent),
        
        
        
        
        Lit(PatLit),
        
        Macro(PatMacro),
        
        Or(PatOr),
        
        
        
        
        
        
        
        Path(PatPath),
        
        Range(PatRange),
        
        Reference(PatReference),
        
        Rest(PatRest),
        
        Slice(PatSlice),
        
        Struct(PatStruct),
        
        Tuple(PatTuple),
        
        TupleStruct(PatTupleStruct),
        
        Type(PatType),
        
        Verbatim(TokenStream),
        
        Wild(PatWild),
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        #[doc(hidden)]
        __TestExhaustive(crate::private),
    }
}
ast_struct! {
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatBox {
        pub attrs: Vec<Attribute>,
        pub box_token: Token![box],
        pub pat: Box<Pat>,
    }
}
ast_struct! {
    
    
    
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatIdent {
        pub attrs: Vec<Attribute>,
        pub by_ref: Option<Token![ref]>,
        pub mutability: Option<Token![mut]>,
        pub ident: Ident,
        pub subpat: Option<(Token![@], Box<Pat>)>,
    }
}
ast_struct! {
    
    
    
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatLit {
        pub attrs: Vec<Attribute>,
        pub expr: Box<Expr>,
    }
}
ast_struct! {
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatMacro {
        pub attrs: Vec<Attribute>,
        pub mac: Macro,
    }
}
ast_struct! {
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatOr {
        pub attrs: Vec<Attribute>,
        pub leading_vert: Option<Token![|]>,
        pub cases: Punctuated<Pat, Token![|]>,
    }
}
ast_struct! {
    
    
    
    
    
    
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatPath {
        pub attrs: Vec<Attribute>,
        pub qself: Option<QSelf>,
        pub path: Path,
    }
}
ast_struct! {
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatRange {
        pub attrs: Vec<Attribute>,
        pub lo: Box<Expr>,
        pub limits: RangeLimits,
        pub hi: Box<Expr>,
    }
}
ast_struct! {
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatReference {
        pub attrs: Vec<Attribute>,
        pub and_token: Token![&],
        pub mutability: Option<Token![mut]>,
        pub pat: Box<Pat>,
    }
}
ast_struct! {
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatRest {
        pub attrs: Vec<Attribute>,
        pub dot2_token: Token![..],
    }
}
ast_struct! {
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatSlice {
        pub attrs: Vec<Attribute>,
        pub bracket_token: token::Bracket,
        pub elems: Punctuated<Pat, Token![,]>,
    }
}
ast_struct! {
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatStruct {
        pub attrs: Vec<Attribute>,
        pub path: Path,
        pub brace_token: token::Brace,
        pub fields: Punctuated<FieldPat, Token![,]>,
        pub dot2_token: Option<Token![..]>,
    }
}
ast_struct! {
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatTuple {
        pub attrs: Vec<Attribute>,
        pub paren_token: token::Paren,
        pub elems: Punctuated<Pat, Token![,]>,
    }
}
ast_struct! {
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatTupleStruct {
        pub attrs: Vec<Attribute>,
        pub path: Path,
        pub pat: PatTuple,
    }
}
ast_struct! {
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatType {
        pub attrs: Vec<Attribute>,
        pub pat: Box<Pat>,
        pub colon_token: Token![:],
        pub ty: Box<Type>,
    }
}
ast_struct! {
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct PatWild {
        pub attrs: Vec<Attribute>,
        pub underscore_token: Token![_],
    }
}
ast_struct! {
    
    
    
    
    
    
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct FieldPat {
        pub attrs: Vec<Attribute>,
        pub member: Member,
        pub colon_token: Option<Token![:]>,
        pub pat: Box<Pat>,
    }
}
#[cfg(feature = "parsing")]
pub mod parsing {
    use super::*;
    use crate::ext::IdentExt;
    use crate::parse::{Parse, ParseBuffer, ParseStream, Result};
    use crate::path;
    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
    impl Parse for Pat {
        fn parse(input: ParseStream) -> Result<Self> {
            let begin = input.fork();
            let lookahead = input.lookahead1();
            if {
                let ahead = input.fork();
                ahead.parse::<Option<Ident>>()?.is_some()
                    && (ahead.peek(Token![::])
                        || ahead.peek(Token![!])
                        || ahead.peek(token::Brace)
                        || ahead.peek(token::Paren)
                        || ahead.peek(Token![..])
                            && ahead.parse::<RangeLimits>().is_ok()
                            && !(ahead.is_empty() || ahead.peek(Token![,])))
            } || {
                let ahead = input.fork();
                ahead.parse::<Option<Token![self]>>()?.is_some() && ahead.peek(Token![::])
            } || lookahead.peek(Token![::])
                || lookahead.peek(Token![<])
                || input.peek(Token![Self])
                || input.peek(Token![super])
                || input.peek(Token![crate])
            {
                pat_path_or_macro_or_struct_or_range(input)
            } else if lookahead.peek(Token![_]) {
                input.call(pat_wild).map(Pat::Wild)
            } else if input.peek(Token![box]) {
                input.call(pat_box).map(Pat::Box)
            } else if input.peek(Token![-]) || lookahead.peek(Lit) || lookahead.peek(Token![const])
            {
                pat_lit_or_range(input)
            } else if lookahead.peek(Token![ref])
                || lookahead.peek(Token![mut])
                || input.peek(Token![self])
                || input.peek(Ident)
            {
                input.call(pat_ident).map(Pat::Ident)
            } else if lookahead.peek(Token![&]) {
                input.call(pat_reference).map(Pat::Reference)
            } else if lookahead.peek(token::Paren) {
                input.call(pat_tuple).map(Pat::Tuple)
            } else if lookahead.peek(token::Bracket) {
                input.call(pat_slice).map(Pat::Slice)
            } else if lookahead.peek(Token![..]) && !input.peek(Token![...]) {
                pat_range_half_open(input, begin)
            } else if lookahead.peek(Token![const]) {
                input.call(pat_const).map(Pat::Verbatim)
            } else {
                Err(lookahead.error())
            }
        }
    }
    fn pat_path_or_macro_or_struct_or_range(input: ParseStream) -> Result<Pat> {
        let begin = input.fork();
        let (qself, path) = path::parsing::qpath(input, true)?;
        if input.peek(Token![..]) {
            return pat_range(input, begin, qself, path);
        }
        if qself.is_some() {
            return Ok(Pat::Path(PatPath {
                attrs: Vec::new(),
                qself,
                path,
            }));
        }
        if input.peek(Token![!]) && !input.peek(Token![!=]) {
            let mut contains_arguments = false;
            for segment in &path.segments {
                match segment.arguments {
                    PathArguments::None => {}
                    PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
                        contains_arguments = true;
                    }
                }
            }
            if !contains_arguments {
                let bang_token: Token![!] = input.parse()?;
                let (delimiter, tokens) = mac::parse_delimiter(input)?;
                return Ok(Pat::Macro(PatMacro {
                    attrs: Vec::new(),
                    mac: Macro {
                        path,
                        bang_token,
                        delimiter,
                        tokens,
                    },
                }));
            }
        }
        if input.peek(token::Brace) {
            pat_struct(input, path).map(Pat::Struct)
        } else if input.peek(token::Paren) {
            pat_tuple_struct(input, path).map(Pat::TupleStruct)
        } else if input.peek(Token![..]) {
            pat_range(input, begin, qself, path)
        } else {
            Ok(Pat::Path(PatPath {
                attrs: Vec::new(),
                qself,
                path,
            }))
        }
    }
    fn pat_wild(input: ParseStream) -> Result<PatWild> {
        Ok(PatWild {
            attrs: Vec::new(),
            underscore_token: input.parse()?,
        })
    }
    fn pat_box(input: ParseStream) -> Result<PatBox> {
        Ok(PatBox {
            attrs: Vec::new(),
            box_token: input.parse()?,
            pat: input.parse()?,
        })
    }
    fn pat_ident(input: ParseStream) -> Result<PatIdent> {
        Ok(PatIdent {
            attrs: Vec::new(),
            by_ref: input.parse()?,
            mutability: input.parse()?,
            ident: input.call(Ident::parse_any)?,
            subpat: {
                if input.peek(Token![@]) {
                    let at_token: Token![@] = input.parse()?;
                    let subpat: Pat = input.parse()?;
                    Some((at_token, Box::new(subpat)))
                } else {
                    None
                }
            },
        })
    }
    fn pat_tuple_struct(input: ParseStream, path: Path) -> Result<PatTupleStruct> {
        Ok(PatTupleStruct {
            attrs: Vec::new(),
            path,
            pat: input.call(pat_tuple)?,
        })
    }
    fn pat_struct(input: ParseStream, path: Path) -> Result<PatStruct> {
        let content;
        let brace_token = braced!(content in input);
        let mut fields = Punctuated::new();
        while !content.is_empty() && !content.peek(Token![..]) {
            let value = content.call(field_pat)?;
            fields.push_value(value);
            if content.is_empty() {
                break;
            }
            let punct: Token![,] = content.parse()?;
            fields.push_punct(punct);
        }
        let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) {
            Some(content.parse()?)
        } else {
            None
        };
        Ok(PatStruct {
            attrs: Vec::new(),
            path,
            brace_token,
            fields,
            dot2_token,
        })
    }
    impl Member {
        fn is_unnamed(&self) -> bool {
            match *self {
                Member::Named(_) => false,
                Member::Unnamed(_) => true,
            }
        }
    }
    fn field_pat(input: ParseStream) -> Result<FieldPat> {
        let attrs = input.call(Attribute::parse_outer)?;
        let boxed: Option<Token![box]> = input.parse()?;
        let by_ref: Option<Token![ref]> = input.parse()?;
        let mutability: Option<Token![mut]> = input.parse()?;
        let member: Member = input.parse()?;
        if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
            || member.is_unnamed()
        {
            return Ok(FieldPat {
                attrs,
                member,
                colon_token: input.parse()?,
                pat: Box::new(multi_pat_with_leading_vert(input)?),
            });
        }
        let ident = match member {
            Member::Named(ident) => ident,
            Member::Unnamed(_) => unreachable!(),
        };
        let mut pat = Pat::Ident(PatIdent {
            attrs: Vec::new(),
            by_ref,
            mutability,
            ident: ident.clone(),
            subpat: None,
        });
        if let Some(boxed) = boxed {
            pat = Pat::Box(PatBox {
                attrs: Vec::new(),
                box_token: boxed,
                pat: Box::new(pat),
            });
        }
        Ok(FieldPat {
            attrs,
            member: Member::Named(ident),
            colon_token: None,
            pat: Box::new(pat),
        })
    }
    fn pat_range(
        input: ParseStream,
        begin: ParseBuffer,
        qself: Option<QSelf>,
        path: Path,
    ) -> Result<Pat> {
        let limits: RangeLimits = input.parse()?;
        let hi = input.call(pat_lit_expr)?;
        if let Some(hi) = hi {
            Ok(Pat::Range(PatRange {
                attrs: Vec::new(),
                lo: Box::new(Expr::Path(ExprPath {
                    attrs: Vec::new(),
                    qself,
                    path,
                })),
                limits,
                hi,
            }))
        } else {
            Ok(Pat::Verbatim(verbatim::between(begin, input)))
        }
    }
    fn pat_range_half_open(input: ParseStream, begin: ParseBuffer) -> Result<Pat> {
        let limits: RangeLimits = input.parse()?;
        let hi = input.call(pat_lit_expr)?;
        if hi.is_some() {
            Ok(Pat::Verbatim(verbatim::between(begin, input)))
        } else {
            match limits {
                RangeLimits::HalfOpen(dot2_token) => Ok(Pat::Rest(PatRest {
                    attrs: Vec::new(),
                    dot2_token,
                })),
                RangeLimits::Closed(_) => Err(input.error("expected range upper bound")),
            }
        }
    }
    fn pat_tuple(input: ParseStream) -> Result<PatTuple> {
        let content;
        let paren_token = parenthesized!(content in input);
        let mut elems = Punctuated::new();
        while !content.is_empty() {
            let value = multi_pat_with_leading_vert(&content)?;
            elems.push_value(value);
            if content.is_empty() {
                break;
            }
            let punct = content.parse()?;
            elems.push_punct(punct);
        }
        Ok(PatTuple {
            attrs: Vec::new(),
            paren_token,
            elems,
        })
    }
    fn pat_reference(input: ParseStream) -> Result<PatReference> {
        Ok(PatReference {
            attrs: Vec::new(),
            and_token: input.parse()?,
            mutability: input.parse()?,
            pat: input.parse()?,
        })
    }
    fn pat_lit_or_range(input: ParseStream) -> Result<Pat> {
        let begin = input.fork();
        let lo = input.call(pat_lit_expr)?.unwrap();
        if input.peek(Token![..]) {
            let limits: RangeLimits = input.parse()?;
            let hi = input.call(pat_lit_expr)?;
            if let Some(hi) = hi {
                Ok(Pat::Range(PatRange {
                    attrs: Vec::new(),
                    lo,
                    limits,
                    hi,
                }))
            } else {
                Ok(Pat::Verbatim(verbatim::between(begin, input)))
            }
        } else if let Expr::Verbatim(verbatim) = *lo {
            Ok(Pat::Verbatim(verbatim))
        } else {
            Ok(Pat::Lit(PatLit {
                attrs: Vec::new(),
                expr: lo,
            }))
        }
    }
    fn pat_lit_expr(input: ParseStream) -> Result<Option<Box<Expr>>> {
        if input.is_empty()
            || input.peek(Token![|])
            || input.peek(Token![=>])
            || input.peek(Token![:]) && !input.peek(Token![::])
            || input.peek(Token![,])
            || input.peek(Token![;])
        {
            return Ok(None);
        }
        let neg: Option<Token![-]> = input.parse()?;
        let lookahead = input.lookahead1();
        let expr = if lookahead.peek(Lit) {
            Expr::Lit(input.parse()?)
        } else if lookahead.peek(Ident)
            || lookahead.peek(Token![::])
            || lookahead.peek(Token![<])
            || lookahead.peek(Token![self])
            || lookahead.peek(Token![Self])
            || lookahead.peek(Token![super])
            || lookahead.peek(Token![crate])
        {
            Expr::Path(input.parse()?)
        } else if lookahead.peek(Token![const]) {
            Expr::Verbatim(input.call(expr::parsing::expr_const)?)
        } else {
            return Err(lookahead.error());
        };
        Ok(Some(Box::new(if let Some(neg) = neg {
            Expr::Unary(ExprUnary {
                attrs: Vec::new(),
                op: UnOp::Neg(neg),
                expr: Box::new(expr),
            })
        } else {
            expr
        })))
    }
    fn pat_slice(input: ParseStream) -> Result<PatSlice> {
        let content;
        let bracket_token = bracketed!(content in input);
        let mut elems = Punctuated::new();
        while !content.is_empty() {
            let value = multi_pat_with_leading_vert(&content)?;
            elems.push_value(value);
            if content.is_empty() {
                break;
            }
            let punct = content.parse()?;
            elems.push_punct(punct);
        }
        Ok(PatSlice {
            attrs: Vec::new(),
            bracket_token,
            elems,
        })
    }
    fn pat_const(input: ParseStream) -> Result<TokenStream> {
        let begin = input.fork();
        input.parse::<Token![const]>()?;
        let content;
        braced!(content in input);
        content.call(Attribute::parse_inner)?;
        content.call(Block::parse_within)?;
        Ok(verbatim::between(begin, input))
    }
    pub fn multi_pat(input: ParseStream) -> Result<Pat> {
        multi_pat_impl(input, None)
    }
    pub fn multi_pat_with_leading_vert(input: ParseStream) -> Result<Pat> {
        let leading_vert: Option<Token![|]> = input.parse()?;
        multi_pat_impl(input, leading_vert)
    }
    fn multi_pat_impl(input: ParseStream, leading_vert: Option<Token![|]>) -> Result<Pat> {
        let mut pat: Pat = input.parse()?;
        if leading_vert.is_some()
            || input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=])
        {
            let mut cases = Punctuated::new();
            cases.push_value(pat);
            while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
                let punct = input.parse()?;
                cases.push_punct(punct);
                let pat: Pat = input.parse()?;
                cases.push_value(pat);
            }
            pat = Pat::Or(PatOr {
                attrs: Vec::new(),
                leading_vert,
                cases,
            });
        }
        Ok(pat)
    }
}
#[cfg(feature = "printing")]
mod printing {
    use super::*;
    use crate::attr::FilterAttrs;
    use proc_macro2::TokenStream;
    use quote::{ToTokens, TokenStreamExt};
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatWild {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.underscore_token.to_tokens(tokens);
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatIdent {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.by_ref.to_tokens(tokens);
            self.mutability.to_tokens(tokens);
            self.ident.to_tokens(tokens);
            if let Some((at_token, subpat)) = &self.subpat {
                at_token.to_tokens(tokens);
                subpat.to_tokens(tokens);
            }
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatStruct {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.path.to_tokens(tokens);
            self.brace_token.surround(tokens, |tokens| {
                self.fields.to_tokens(tokens);
                
                if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
                    <Token![,]>::default().to_tokens(tokens);
                }
                self.dot2_token.to_tokens(tokens);
            });
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatTupleStruct {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.path.to_tokens(tokens);
            self.pat.to_tokens(tokens);
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatType {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.pat.to_tokens(tokens);
            self.colon_token.to_tokens(tokens);
            self.ty.to_tokens(tokens);
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatPath {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            private::print_path(tokens, &self.qself, &self.path);
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatTuple {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.paren_token.surround(tokens, |tokens| {
                self.elems.to_tokens(tokens);
            });
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatBox {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.box_token.to_tokens(tokens);
            self.pat.to_tokens(tokens);
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatReference {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.and_token.to_tokens(tokens);
            self.mutability.to_tokens(tokens);
            self.pat.to_tokens(tokens);
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatRest {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.dot2_token.to_tokens(tokens);
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatLit {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.expr.to_tokens(tokens);
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatRange {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.lo.to_tokens(tokens);
            match &self.limits {
                RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
                RangeLimits::Closed(t) => t.to_tokens(tokens),
            }
            self.hi.to_tokens(tokens);
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatSlice {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.bracket_token.surround(tokens, |tokens| {
                self.elems.to_tokens(tokens);
            });
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatMacro {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.mac.to_tokens(tokens);
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for PatOr {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            self.leading_vert.to_tokens(tokens);
            self.cases.to_tokens(tokens);
        }
    }
    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for FieldPat {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.outer());
            if let Some(colon_token) = &self.colon_token {
                self.member.to_tokens(tokens);
                colon_token.to_tokens(tokens);
            }
            self.pat.to_tokens(tokens);
        }
    }
}