diff --git a/crates/hir/src/hir_def/item.rs b/crates/hir/src/hir_def/item.rs index 1efd316fd..535de254f 100644 --- a/crates/hir/src/hir_def/item.rs +++ b/crates/hir/src/hir_def/item.rs @@ -1093,6 +1093,7 @@ impl<'db> FieldDefListId<'db> { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FieldDef<'db> { + pub attributes: AttrListId<'db>, pub name: Partial>, pub ty: Partial>, pub vis: Visibility, @@ -1106,6 +1107,7 @@ pub struct VariantDefListId<'db> { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct VariantDef<'db> { + pub attributes: AttrListId<'db>, pub name: Partial>, pub kind: VariantKind<'db>, } diff --git a/crates/hir/src/lower/item.rs b/crates/hir/src/lower/item.rs index 2e2fa4f80..222ef8bc3 100644 --- a/crates/hir/src/lower/item.rs +++ b/crates/hir/src/lower/item.rs @@ -392,6 +392,7 @@ impl<'db> FieldDefListId<'db> { impl<'db> FieldDef<'db> { fn lower_ast(ctxt: &mut FileLowerCtxt<'db>, ast: ast::RecordFieldDef) -> Self { + let attributes = AttrListId::lower_ast_opt(ctxt, ast.attr_list()); let name = IdentId::lower_token_partial(ctxt, ast.name()); let ty = TypeId::lower_ast_partial(ctxt, ast.ty()); let vis = if ast.pub_kw().is_some() { @@ -400,7 +401,12 @@ impl<'db> FieldDef<'db> { Visibility::Private }; - Self { name, ty, vis } + Self { + attributes, + name, + ty, + vis, + } } } @@ -421,12 +427,18 @@ impl<'db> VariantDefListId<'db> { impl<'db> VariantDef<'db> { fn lower_ast(ctxt: &mut FileLowerCtxt<'db>, ast: ast::VariantDef) -> Self { + let attributes = AttrListId::lower_ast_opt(ctxt, ast.attr_list()); let name = IdentId::lower_token_partial(ctxt, ast.name()); let kind = match ast.kind() { ast::VariantKind::Unit => VariantKind::Unit, ast::VariantKind::Tuple(t) => VariantKind::Tuple(TupleTypeId::lower_ast(ctxt, t)), ast::VariantKind::Record(r) => VariantKind::Record(FieldDefListId::lower_ast(ctxt, r)), }; - Self { name, kind } + + Self { + attributes, + name, + kind, + } } } diff --git a/crates/parser2/src/ast/item.rs b/crates/parser2/src/ast/item.rs index 132ff881b..9626764f1 100644 --- a/crates/parser2/src/ast/item.rs +++ b/crates/parser2/src/ast/item.rs @@ -1,8 +1,8 @@ +use rowan::ast::{support, AstNode}; + use super::{ast_node, TraitRef, TupleType}; use crate::{FeLang, SyntaxKind as SK, SyntaxToken}; -use rowan::ast::{support, AstNode}; - ast_node! { /// The top-level node of the AST tree. pub struct Root, @@ -334,6 +334,7 @@ ast_node! { pub struct RecordFieldDef, SK::RecordFieldDef, } +impl super::AttrListOwner for RecordFieldDef {} impl RecordFieldDef { /// Returns the pub keyword if exists. pub fn pub_kw(&self) -> Option { @@ -362,6 +363,7 @@ ast_node! { pub struct VariantDef, SK::VariantDef, } +impl super::AttrListOwner for VariantDef {} impl VariantDef { /// Returns the name of the variant. /// `Foo` in `Foo(i32, u32)` @@ -458,16 +460,15 @@ pub enum ItemKind { #[cfg(test)] mod tests { + use wasm_bindgen_test::wasm_bindgen_test; + + use super::*; use crate::{ ast::{prelude::*, ExprKind, TypeKind}, lexer::Lexer, parser::{ItemListScope, Parser}, }; - use super::*; - - use wasm_bindgen_test::wasm_bindgen_test; - fn parse_item(source: &str) -> T where T: TryFrom, diff --git a/crates/parser2/src/parser/item.rs b/crates/parser2/src/parser/item.rs index 49e7aca5b..d41f17322 100644 --- a/crates/parser2/src/parser/item.rs +++ b/crates/parser2/src/parser/item.rs @@ -2,10 +2,9 @@ use std::{cell::Cell, convert::Infallible, rc::Rc}; use unwrap_infallible::UnwrapInfallible; -use crate::{parser::func::FuncScope, ExpectedKind, SyntaxKind}; - use super::{ - attr, define_scope, + attr::{self, parse_attr_list}, + define_scope, expr::parse_expr, func::FuncDefScope, param::{parse_generic_params_opt, parse_where_clause_opt, TraitRefScope}, @@ -16,6 +15,7 @@ use super::{ use_tree::UseTreeScope, ErrProof, Parser, Recovery, }; +use crate::{parser::func::FuncScope, ExpectedKind, SyntaxKind}; define_scope! { #[doc(hidden)] @@ -318,6 +318,7 @@ define_scope! { VariantDefScope, VariantDef } impl super::Parse for VariantDefScope { type Error = Recovery; fn parse(&mut self, parser: &mut Parser) -> Result<(), Self::Error> { + parse_attr_list(parser)?; parser.bump_or_recover(SyntaxKind::Ident, "expected ident for the variant name")?; if parser.current_kind() == Some(SyntaxKind::LParen) { @@ -471,8 +472,9 @@ impl super::Parse for ConstScope { type Error = Recovery; fn parse(&mut self, parser: &mut Parser) -> Result<(), Self::Error> { - parser.bump_expected(SyntaxKind::ConstKw); + parse_attr_list(parser)?; + parser.bump_expected(SyntaxKind::ConstKw); parser.set_newline_as_trivia(false); parser.set_scope_recovery_stack(&[SyntaxKind::Ident, SyntaxKind::Colon, SyntaxKind::Eq]); diff --git a/crates/parser2/test_files/syntax_node/items/enums.fe b/crates/parser2/test_files/syntax_node/items/enums.fe index f341d285b..41e73a2ab 100644 --- a/crates/parser2/test_files/syntax_node/items/enums.fe +++ b/crates/parser2/test_files/syntax_node/items/enums.fe @@ -13,7 +13,10 @@ enum RecordVariants { enum Option where T: Clone { + /// Some value of type `T` Some(T), + + /// No value. None, } diff --git a/crates/parser2/test_files/syntax_node/items/enums.snap b/crates/parser2/test_files/syntax_node/items/enums.snap index c86189673..cf4835733 100644 --- a/crates/parser2/test_files/syntax_node/items/enums.snap +++ b/crates/parser2/test_files/syntax_node/items/enums.snap @@ -3,8 +3,8 @@ source: crates/parser2/tests/syntax_node.rs expression: node input_file: crates/parser2/test_files/syntax_node/items/enums.fe --- -Root@0..493 - ItemList@0..492 +Root@0..547 + ItemList@0..546 Item@0..13 Enum@0..13 EnumKw@0..4 "enum" @@ -106,8 +106,8 @@ Root@0..493 Newline@138..139 "\n" RBrace@139..140 "}" Newline@140..142 "\n\n" - Item@142..202 - Enum@142..202 + Item@142..256 + Enum@142..256 EnumKw@142..146 "enum" WhiteSpace@146..147 " " Ident@147..153 "Option" @@ -135,349 +135,360 @@ Root@0..493 PathSegment@170..175 Ident@170..175 "Clone" Newline@175..176 "\n" - VariantDefList@176..202 + VariantDefList@176..256 LBrace@176..177 "{" Newline@177..178 "\n" WhiteSpace@178..182 " " - VariantDef@182..189 - Ident@182..186 "Some" - TupleType@186..189 - LParen@186..187 "(" - PathType@187..188 - Path@187..188 - PathSegment@187..188 - Ident@187..188 "T" - RParen@188..189 ")" - Comma@189..190 "," - Newline@190..191 "\n" - WhiteSpace@191..195 " " - VariantDef@195..199 - Ident@195..199 "None" - Comma@199..200 "," - Newline@200..201 "\n" - RBrace@201..202 "}" - Newline@202..204 "\n\n" - Item@204..306 - Enum@204..306 - EnumKw@204..208 "enum" - WhiteSpace@208..209 " " - Ident@209..218 "BoundEnum" - GenericParamList@218..247 - Lt@218..219 "<" - TypeGenericParam@219..231 - Ident@219..220 "T" - TypeBoundList@220..231 - Colon@220..221 ":" - WhiteSpace@221..222 " " - TypeBound@222..225 - TraitRef@222..225 - Path@222..225 - PathSegment@222..225 - Ident@222..225 "Add" - WhiteSpace@225..226 " " - Plus@226..227 "+" - WhiteSpace@227..228 " " - TypeBound@228..231 - TraitRef@228..231 - Path@228..231 - PathSegment@228..231 - Ident@228..231 "Mul" - WhiteSpace@231..232 " " - Comma@232..233 "," - WhiteSpace@233..234 " " - TypeGenericParam@234..246 - Ident@234..235 "U" - TypeBoundList@235..246 - Colon@235..236 ":" - WhiteSpace@236..237 " " - TypeBound@237..240 - TraitRef@237..240 - Path@237..240 - PathSegment@237..240 - Ident@237..240 "Sub" - WhiteSpace@240..241 " " - Plus@241..242 "+" - WhiteSpace@242..243 " " - TypeBound@243..246 - TraitRef@243..246 - Path@243..246 - PathSegment@243..246 - Ident@243..246 "Div" - Gt@246..247 ">" - Newline@247..248 "\n" - WhereClause@248..272 - WhereKw@248..253 "where" - WhiteSpace@253..254 " " - WherePredicate@254..272 - PathType@254..265 - Path@254..265 - PathSegment@254..257 - Ident@254..257 "Foo" - Colon2@257..259 "::" - PathSegment@259..265 - Ident@259..262 "Bar" - GenericArgList@262..265 - Lt@262..263 "<" - TypeGenericArg@263..264 - PathType@263..264 - Path@263..264 - PathSegment@263..264 - Ident@263..264 "T" - Gt@264..265 ">" - TypeBoundList@265..272 - Colon@265..266 ":" - WhiteSpace@266..267 " " - TypeBound@267..272 - TraitRef@267..272 - Path@267..272 - PathSegment@267..272 - Ident@267..272 "Trait" - Newline@272..273 "\n" - VariantDefList@273..306 - LBrace@273..274 "{" - Newline@274..275 "\n" - WhiteSpace@275..279 " " - VariantDef@279..288 - Ident@279..285 "AddMul" - TupleType@285..288 - LParen@285..286 "(" - PathType@286..287 - Path@286..287 - PathSegment@286..287 - Ident@286..287 "T" - RParen@287..288 ")" - Comma@288..289 "," - Newline@289..290 "\n" - WhiteSpace@290..294 " " - VariantDef@294..303 - Ident@294..300 "SubDiv" - TupleType@300..303 - LParen@300..301 "(" - PathType@301..302 - Path@301..302 - PathSegment@301..302 - Ident@301..302 "U" - RParen@302..303 ")" - Comma@303..304 "," - Newline@304..305 "\n" - RBrace@305..306 "}" - Newline@306..308 "\n\n" - Item@308..434 - Enum@308..434 - EnumKw@308..312 "enum" - WhiteSpace@312..313 " " - Ident@313..320 "HKTEnum" - GenericParamList@320..340 - Lt@320..321 "<" - TypeGenericParam@321..330 - Ident@321..322 "T" - TypeBoundList@322..330 - Colon@322..323 ":" - WhiteSpace@323..324 " " - TypeBound@324..330 - KindBoundAbs@324..330 - KindBoundMono@324..325 - Star@324..325 "*" - WhiteSpace@325..326 " " - Arrow@326..328 "->" - WhiteSpace@328..329 " " - KindBoundMono@329..330 - Star@329..330 "*" - Comma@330..331 "," - WhiteSpace@331..332 " " - TypeGenericParam@332..333 - Ident@332..333 "U" - Comma@333..334 "," - WhiteSpace@334..335 " " - TypeGenericParam@335..336 - Ident@335..336 "V" - Comma@336..337 "," - WhiteSpace@337..338 " " - TypeGenericParam@338..339 - Ident@338..339 "W" - Gt@339..340 ">" - Newline@340..341 "\n" - WhereClause@341..416 - WhereKw@341..346 "where" - Newline@346..347 "\n" - WhiteSpace@347..350 " " - WherePredicate@350..366 - PathType@350..351 - Path@350..351 - PathSegment@350..351 - Ident@350..351 "U" - TypeBoundList@351..366 - Colon@351..352 ":" - WhiteSpace@352..353 " " - TypeBound@353..366 - KindBoundAbs@353..366 - LParen@353..354 "(" - KindBoundAbs@354..360 - KindBoundMono@354..355 - Star@354..355 "*" - WhiteSpace@355..356 " " - Arrow@356..358 "->" - WhiteSpace@358..359 " " - KindBoundMono@359..360 - Star@359..360 "*" - RParen@360..361 ")" - WhiteSpace@361..362 " " - Arrow@362..364 "->" - WhiteSpace@364..365 " " - KindBoundMono@365..366 - Star@365..366 "*" - Comma@366..367 "," - Newline@367..368 "\n" - WhiteSpace@368..371 " " - WherePredicate@371..392 - PathType@371..372 - Path@371..372 - PathSegment@371..372 - Ident@371..372 "V" - TypeBoundList@372..392 - Colon@372..373 ":" - WhiteSpace@373..374 " " - TypeBound@374..392 - KindBoundAbs@374..392 - KindBoundMono@374..375 - Star@374..375 "*" - WhiteSpace@375..376 " " - Arrow@376..378 "->" - KindBoundAbs@378..392 - WhiteSpace@378..379 " " - KindBoundMono@379..380 - Star@379..380 "*" - WhiteSpace@380..381 " " - Arrow@381..383 "->" - WhiteSpace@383..384 " " - LParen@384..385 "(" - KindBoundAbs@385..391 - KindBoundMono@385..386 - Star@385..386 "*" - WhiteSpace@386..387 " " - Arrow@387..389 "->" - WhiteSpace@389..390 " " - KindBoundMono@390..391 - Star@390..391 "*" - RParen@391..392 ")" - Comma@392..393 "," - Newline@393..394 "\n" - WhiteSpace@394..397 " " - WherePredicate@397..416 - PathType@397..398 - Path@397..398 - PathSegment@397..398 - Ident@397..398 "W" - TypeBoundList@398..416 - Colon@398..399 ":" - WhiteSpace@399..400 " " - TypeBound@400..416 - KindBoundAbs@400..416 - KindBoundMono@400..401 - Star@400..401 "*" - WhiteSpace@401..402 " " - Arrow@402..404 "->" - KindBoundAbs@404..416 - WhiteSpace@404..405 " " - KindBoundMono@405..406 - Star@405..406 "*" - WhiteSpace@406..407 " " - Arrow@407..409 "->" - KindBoundAbs@409..416 - WhiteSpace@409..410 " " - KindBoundMono@410..411 - Star@410..411 "*" - WhiteSpace@411..412 " " - Arrow@412..414 "->" - WhiteSpace@414..415 " " - KindBoundMono@415..416 - Star@415..416 "*" - Newline@416..417 "\n" - VariantDefList@417..434 - LBrace@417..418 "{" - Newline@418..419 "\n" - WhiteSpace@419..423 " " - VariantDef@423..432 - Ident@423..426 "Foo" - TupleType@426..432 - LParen@426..427 "(" - PathType@427..431 - Path@427..431 - PathSegment@427..431 - Ident@427..428 "U" - GenericArgList@428..431 - Lt@428..429 "<" - TypeGenericArg@429..430 - PathType@429..430 - Path@429..430 - PathSegment@429..430 - Ident@429..430 "T" - Gt@430..431 ">" - RParen@431..432 ")" - Newline@432..433 "\n" - RBrace@433..434 "}" - Newline@434..436 "\n\n" - Item@436..492 - Enum@436..492 - EnumKw@436..440 "enum" - WhiteSpace@440..441 " " - Ident@441..451 "SingleLine" - WhiteSpace@451..452 " " - VariantDefList@452..492 - LBrace@452..453 "{" - WhiteSpace@453..454 " " - VariantDef@454..455 - Ident@454..455 "A" - Comma@455..456 "," - WhiteSpace@456..457 " " - VariantDef@457..458 - Ident@457..458 "B" - Comma@458..459 "," - WhiteSpace@459..460 " " - VariantDef@460..479 - Ident@460..461 "C" - WhiteSpace@461..462 " " - RecordFieldDefList@462..479 - LBrace@462..463 "{" - WhiteSpace@463..464 " " - RecordFieldDef@464..470 - Ident@464..465 "x" - Colon@465..466 ":" - WhiteSpace@466..467 " " - PathType@467..470 - Path@467..470 - PathSegment@467..470 - Ident@467..470 "i32" - Comma@470..471 "," - WhiteSpace@471..472 " " - RecordFieldDef@472..477 - Ident@472..473 "y" - Colon@473..474 ":" - WhiteSpace@474..475 " " - PathType@475..477 - Path@475..477 - PathSegment@475..477 - Ident@475..477 "u8" - WhiteSpace@477..478 " " - RBrace@478..479 "}" - Comma@479..480 "," - WhiteSpace@480..481 " " - VariantDef@481..490 - Ident@481..482 "D" - TupleType@482..490 - LParen@482..483 "(" - PathType@483..485 - Path@483..485 - PathSegment@483..485 - Ident@483..485 "i8" - Comma@485..486 "," - WhiteSpace@486..487 " " - PathType@487..489 - Path@487..489 - PathSegment@487..489 - Ident@487..489 "i8" - RParen@489..490 ")" - WhiteSpace@490..491 " " - RBrace@491..492 "}" - Newline@492..493 "\n" - + VariantDef@182..220 + AttrList@182..209 + DocCommentAttr@182..208 + DocComment@182..208 "/// Some value of typ ..." + Newline@208..209 "\n" + WhiteSpace@209..213 " " + Ident@213..217 "Some" + TupleType@217..220 + LParen@217..218 "(" + PathType@218..219 + Path@218..219 + PathSegment@218..219 + Ident@218..219 "T" + RParen@219..220 ")" + Comma@220..221 "," + Newline@221..222 "\n" + WhiteSpace@222..226 " " + Newline@226..227 "\n" + WhiteSpace@227..231 " " + VariantDef@231..253 + AttrList@231..245 + DocCommentAttr@231..244 + DocComment@231..244 "/// No value." + Newline@244..245 "\n" + WhiteSpace@245..249 " " + Ident@249..253 "None" + Comma@253..254 "," + Newline@254..255 "\n" + RBrace@255..256 "}" + Newline@256..258 "\n\n" + Item@258..360 + Enum@258..360 + EnumKw@258..262 "enum" + WhiteSpace@262..263 " " + Ident@263..272 "BoundEnum" + GenericParamList@272..301 + Lt@272..273 "<" + TypeGenericParam@273..285 + Ident@273..274 "T" + TypeBoundList@274..285 + Colon@274..275 ":" + WhiteSpace@275..276 " " + TypeBound@276..279 + TraitRef@276..279 + Path@276..279 + PathSegment@276..279 + Ident@276..279 "Add" + WhiteSpace@279..280 " " + Plus@280..281 "+" + WhiteSpace@281..282 " " + TypeBound@282..285 + TraitRef@282..285 + Path@282..285 + PathSegment@282..285 + Ident@282..285 "Mul" + WhiteSpace@285..286 " " + Comma@286..287 "," + WhiteSpace@287..288 " " + TypeGenericParam@288..300 + Ident@288..289 "U" + TypeBoundList@289..300 + Colon@289..290 ":" + WhiteSpace@290..291 " " + TypeBound@291..294 + TraitRef@291..294 + Path@291..294 + PathSegment@291..294 + Ident@291..294 "Sub" + WhiteSpace@294..295 " " + Plus@295..296 "+" + WhiteSpace@296..297 " " + TypeBound@297..300 + TraitRef@297..300 + Path@297..300 + PathSegment@297..300 + Ident@297..300 "Div" + Gt@300..301 ">" + Newline@301..302 "\n" + WhereClause@302..326 + WhereKw@302..307 "where" + WhiteSpace@307..308 " " + WherePredicate@308..326 + PathType@308..319 + Path@308..319 + PathSegment@308..311 + Ident@308..311 "Foo" + Colon2@311..313 "::" + PathSegment@313..319 + Ident@313..316 "Bar" + GenericArgList@316..319 + Lt@316..317 "<" + TypeGenericArg@317..318 + PathType@317..318 + Path@317..318 + PathSegment@317..318 + Ident@317..318 "T" + Gt@318..319 ">" + TypeBoundList@319..326 + Colon@319..320 ":" + WhiteSpace@320..321 " " + TypeBound@321..326 + TraitRef@321..326 + Path@321..326 + PathSegment@321..326 + Ident@321..326 "Trait" + Newline@326..327 "\n" + VariantDefList@327..360 + LBrace@327..328 "{" + Newline@328..329 "\n" + WhiteSpace@329..333 " " + VariantDef@333..342 + Ident@333..339 "AddMul" + TupleType@339..342 + LParen@339..340 "(" + PathType@340..341 + Path@340..341 + PathSegment@340..341 + Ident@340..341 "T" + RParen@341..342 ")" + Comma@342..343 "," + Newline@343..344 "\n" + WhiteSpace@344..348 " " + VariantDef@348..357 + Ident@348..354 "SubDiv" + TupleType@354..357 + LParen@354..355 "(" + PathType@355..356 + Path@355..356 + PathSegment@355..356 + Ident@355..356 "U" + RParen@356..357 ")" + Comma@357..358 "," + Newline@358..359 "\n" + RBrace@359..360 "}" + Newline@360..362 "\n\n" + Item@362..488 + Enum@362..488 + EnumKw@362..366 "enum" + WhiteSpace@366..367 " " + Ident@367..374 "HKTEnum" + GenericParamList@374..394 + Lt@374..375 "<" + TypeGenericParam@375..384 + Ident@375..376 "T" + TypeBoundList@376..384 + Colon@376..377 ":" + WhiteSpace@377..378 " " + TypeBound@378..384 + KindBoundAbs@378..384 + KindBoundMono@378..379 + Star@378..379 "*" + WhiteSpace@379..380 " " + Arrow@380..382 "->" + WhiteSpace@382..383 " " + KindBoundMono@383..384 + Star@383..384 "*" + Comma@384..385 "," + WhiteSpace@385..386 " " + TypeGenericParam@386..387 + Ident@386..387 "U" + Comma@387..388 "," + WhiteSpace@388..389 " " + TypeGenericParam@389..390 + Ident@389..390 "V" + Comma@390..391 "," + WhiteSpace@391..392 " " + TypeGenericParam@392..393 + Ident@392..393 "W" + Gt@393..394 ">" + Newline@394..395 "\n" + WhereClause@395..470 + WhereKw@395..400 "where" + Newline@400..401 "\n" + WhiteSpace@401..404 " " + WherePredicate@404..420 + PathType@404..405 + Path@404..405 + PathSegment@404..405 + Ident@404..405 "U" + TypeBoundList@405..420 + Colon@405..406 ":" + WhiteSpace@406..407 " " + TypeBound@407..420 + KindBoundAbs@407..420 + LParen@407..408 "(" + KindBoundAbs@408..414 + KindBoundMono@408..409 + Star@408..409 "*" + WhiteSpace@409..410 " " + Arrow@410..412 "->" + WhiteSpace@412..413 " " + KindBoundMono@413..414 + Star@413..414 "*" + RParen@414..415 ")" + WhiteSpace@415..416 " " + Arrow@416..418 "->" + WhiteSpace@418..419 " " + KindBoundMono@419..420 + Star@419..420 "*" + Comma@420..421 "," + Newline@421..422 "\n" + WhiteSpace@422..425 " " + WherePredicate@425..446 + PathType@425..426 + Path@425..426 + PathSegment@425..426 + Ident@425..426 "V" + TypeBoundList@426..446 + Colon@426..427 ":" + WhiteSpace@427..428 " " + TypeBound@428..446 + KindBoundAbs@428..446 + KindBoundMono@428..429 + Star@428..429 "*" + WhiteSpace@429..430 " " + Arrow@430..432 "->" + KindBoundAbs@432..446 + WhiteSpace@432..433 " " + KindBoundMono@433..434 + Star@433..434 "*" + WhiteSpace@434..435 " " + Arrow@435..437 "->" + WhiteSpace@437..438 " " + LParen@438..439 "(" + KindBoundAbs@439..445 + KindBoundMono@439..440 + Star@439..440 "*" + WhiteSpace@440..441 " " + Arrow@441..443 "->" + WhiteSpace@443..444 " " + KindBoundMono@444..445 + Star@444..445 "*" + RParen@445..446 ")" + Comma@446..447 "," + Newline@447..448 "\n" + WhiteSpace@448..451 " " + WherePredicate@451..470 + PathType@451..452 + Path@451..452 + PathSegment@451..452 + Ident@451..452 "W" + TypeBoundList@452..470 + Colon@452..453 ":" + WhiteSpace@453..454 " " + TypeBound@454..470 + KindBoundAbs@454..470 + KindBoundMono@454..455 + Star@454..455 "*" + WhiteSpace@455..456 " " + Arrow@456..458 "->" + KindBoundAbs@458..470 + WhiteSpace@458..459 " " + KindBoundMono@459..460 + Star@459..460 "*" + WhiteSpace@460..461 " " + Arrow@461..463 "->" + KindBoundAbs@463..470 + WhiteSpace@463..464 " " + KindBoundMono@464..465 + Star@464..465 "*" + WhiteSpace@465..466 " " + Arrow@466..468 "->" + WhiteSpace@468..469 " " + KindBoundMono@469..470 + Star@469..470 "*" + Newline@470..471 "\n" + VariantDefList@471..488 + LBrace@471..472 "{" + Newline@472..473 "\n" + WhiteSpace@473..477 " " + VariantDef@477..486 + Ident@477..480 "Foo" + TupleType@480..486 + LParen@480..481 "(" + PathType@481..485 + Path@481..485 + PathSegment@481..485 + Ident@481..482 "U" + GenericArgList@482..485 + Lt@482..483 "<" + TypeGenericArg@483..484 + PathType@483..484 + Path@483..484 + PathSegment@483..484 + Ident@483..484 "T" + Gt@484..485 ">" + RParen@485..486 ")" + Newline@486..487 "\n" + RBrace@487..488 "}" + Newline@488..490 "\n\n" + Item@490..546 + Enum@490..546 + EnumKw@490..494 "enum" + WhiteSpace@494..495 " " + Ident@495..505 "SingleLine" + WhiteSpace@505..506 " " + VariantDefList@506..546 + LBrace@506..507 "{" + WhiteSpace@507..508 " " + VariantDef@508..509 + Ident@508..509 "A" + Comma@509..510 "," + WhiteSpace@510..511 " " + VariantDef@511..512 + Ident@511..512 "B" + Comma@512..513 "," + WhiteSpace@513..514 " " + VariantDef@514..533 + Ident@514..515 "C" + WhiteSpace@515..516 " " + RecordFieldDefList@516..533 + LBrace@516..517 "{" + WhiteSpace@517..518 " " + RecordFieldDef@518..524 + Ident@518..519 "x" + Colon@519..520 ":" + WhiteSpace@520..521 " " + PathType@521..524 + Path@521..524 + PathSegment@521..524 + Ident@521..524 "i32" + Comma@524..525 "," + WhiteSpace@525..526 " " + RecordFieldDef@526..531 + Ident@526..527 "y" + Colon@527..528 ":" + WhiteSpace@528..529 " " + PathType@529..531 + Path@529..531 + PathSegment@529..531 + Ident@529..531 "u8" + WhiteSpace@531..532 " " + RBrace@532..533 "}" + Comma@533..534 "," + WhiteSpace@534..535 " " + VariantDef@535..544 + Ident@535..536 "D" + TupleType@536..544 + LParen@536..537 "(" + PathType@537..539 + Path@537..539 + PathSegment@537..539 + Ident@537..539 "i8" + Comma@539..540 "," + WhiteSpace@540..541 " " + PathType@541..543 + Path@541..543 + PathSegment@541..543 + Ident@541..543 "i8" + RParen@543..544 ")" + WhiteSpace@544..545 " " + RBrace@545..546 "}" + Newline@546..547 "\n"