@@ -525,38 +525,36 @@ impl AttrsWithOwner {
525525
526526fn inner_attributes (
527527 syntax : & SyntaxNode ,
528- ) -> Option < ( impl Iterator < Item = ast:: Attr > , impl Iterator < Item = ast:: Comment > ) > {
529- let ( attrs , docs ) = match_ast ! {
528+ ) -> Option < impl Iterator < Item = Either < ast:: Attr , ast:: Comment > > > {
529+ let node = match_ast ! {
530530 match syntax {
531- ast:: SourceFile ( it ) => ( it . attrs ( ) , ast :: DocCommentIter :: from_syntax_node ( it . syntax ( ) ) ) ,
532- ast:: ExternBlock ( it) => {
533- let extern_item_list = it. extern_item_list ( ) ?;
534- ( extern_item_list . attrs ( ) , ast :: DocCommentIter :: from_syntax_node ( extern_item_list . syntax( ) ) )
535- } ,
536- ast:: Fn ( it) => {
537- let body = it . body ( ) ? ;
538- let stmt_list = body . stmt_list ( ) ? ;
539- ( stmt_list . attrs ( ) , ast :: DocCommentIter :: from_syntax_node ( body . syntax ( ) ) )
540- } ,
541- ast :: Impl ( it ) => {
542- let assoc_item_list = it . assoc_item_list ( ) ? ;
543- ( assoc_item_list . attrs ( ) , ast :: DocCommentIter :: from_syntax_node ( assoc_item_list . syntax ( ) ) )
544- } ,
545- ast :: Module ( it ) => {
546- let item_list = it . item_list ( ) ? ;
547- ( item_list . attrs ( ) , ast :: DocCommentIter :: from_syntax_node ( item_list . syntax ( ) ) )
531+ ast:: SourceFile ( _ ) => syntax . clone ( ) ,
532+ ast:: ExternBlock ( it) => it . extern_item_list ( ) ? . syntax ( ) . clone ( ) ,
533+ ast :: Fn ( it ) => it. body ( ) ?. stmt_list ( ) ? . syntax ( ) . clone ( ) ,
534+ ast :: Impl ( it ) => it . assoc_item_list ( ) ? . syntax( ) . clone ( ) ,
535+ ast :: Module ( it ) => it . item_list ( ) ? . syntax ( ) . clone ( ) ,
536+ ast:: BlockExpr ( it) => {
537+ use syntax :: SyntaxKind :: { BLOCK_EXPR , EXPR_STMT } ;
538+ // Block expressions accept outer and inner attributes, but only when they are the outer
539+ // expression of an expression statement or the final expression of another block expression.
540+ let may_carry_attributes = matches! (
541+ it . syntax ( ) . parent ( ) . map ( |it| it . kind ( ) ) ,
542+ Some ( BLOCK_EXPR | EXPR_STMT )
543+ ) ;
544+ if !may_carry_attributes {
545+ return None
546+ }
547+ syntax . clone ( )
548548 } ,
549- // FIXME: BlockExpr's only accept inner attributes in specific cases
550- // Excerpt from the reference:
551- // Block expressions accept outer and inner attributes, but only when they are the outer
552- // expression of an expression statement or the final expression of another block expression.
553- ast:: BlockExpr ( _it) => return None ,
554549 _ => return None ,
555550 }
556551 } ;
557- let attrs = attrs. filter ( |attr| attr. kind ( ) . is_inner ( ) ) ;
558- let docs = docs. filter ( |doc| doc. is_inner ( ) ) ;
559- Some ( ( attrs, docs) )
552+
553+ let attrs = ast:: AttrDocCommentIter :: from_syntax_node ( & node) . filter ( |el| match el {
554+ Either :: Left ( attr) => attr. kind ( ) . is_inner ( ) ,
555+ Either :: Right ( comment) => comment. is_inner ( ) ,
556+ } ) ;
557+ Some ( attrs)
560558}
561559
562560#[ derive( Debug ) ]
@@ -833,24 +831,16 @@ fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase
833831fn collect_attrs (
834832 owner : & dyn ast:: HasAttrs ,
835833) -> impl Iterator < Item = ( AttrId , Either < ast:: Attr , ast:: Comment > ) > {
836- let ( inner_attrs, inner_docs) = inner_attributes ( owner. syntax ( ) )
837- . map_or ( ( None , None ) , |( attrs, docs) | ( Some ( attrs) , Some ( docs) ) ) ;
838-
839- let outer_attrs = owner. attrs ( ) . filter ( |attr| attr. kind ( ) . is_outer ( ) ) ;
840- let attrs = outer_attrs
841- . chain ( inner_attrs. into_iter ( ) . flatten ( ) )
842- . map ( |attr| ( attr. syntax ( ) . text_range ( ) . start ( ) , Either :: Left ( attr) ) ) ;
843-
844- let outer_docs =
845- ast:: DocCommentIter :: from_syntax_node ( owner. syntax ( ) ) . filter ( ast:: Comment :: is_outer) ;
846- let docs = outer_docs
847- . chain ( inner_docs. into_iter ( ) . flatten ( ) )
848- . map ( |docs_text| ( docs_text. syntax ( ) . text_range ( ) . start ( ) , Either :: Right ( docs_text) ) ) ;
849- // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved
850- docs. chain ( attrs)
851- . sorted_by_key ( |& ( offset, _) | offset)
834+ let inner_attrs = inner_attributes ( owner. syntax ( ) ) . into_iter ( ) . flatten ( ) ;
835+ let outer_attrs =
836+ ast:: AttrDocCommentIter :: from_syntax_node ( owner. syntax ( ) ) . filter ( |el| match el {
837+ Either :: Left ( attr) => attr. kind ( ) . is_outer ( ) ,
838+ Either :: Right ( comment) => comment. is_outer ( ) ,
839+ } ) ;
840+ outer_attrs
841+ . chain ( inner_attrs)
852842 . enumerate ( )
853- . map ( |( id, ( _ , attr) ) | ( AttrId { ast_index : id as u32 } , attr) )
843+ . map ( |( id, attr) | ( AttrId { ast_index : id as u32 } , attr) )
854844}
855845
856846pub ( crate ) fn variants_attrs_source_map (
0 commit comments