From 5f89a60f1a0feab1e2e0dd37e642877552675da4 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 19 Apr 2021 17:11:49 +0300 Subject: fix: false positive about inner attrs in docs closes #8541 --- crates/hir_def/src/attr.rs | 4 +- crates/syntax/src/ast/node_ext.rs | 12 ++ crates/syntax/src/validation/block.rs | 2 +- .../test_data/parser/ok/0045_block_attrs.rast | 218 +++++++++++++++++++++ .../syntax/test_data/parser/ok/0045_block_attrs.rs | 24 +++ .../parser/ok/0045_block_inner_attrs.rast | 178 ----------------- .../test_data/parser/ok/0045_block_inner_attrs.rs | 20 -- 7 files changed, 257 insertions(+), 201 deletions(-) create mode 100644 crates/syntax/test_data/parser/ok/0045_block_attrs.rast create mode 100644 crates/syntax/test_data/parser/ok/0045_block_attrs.rs delete mode 100644 crates/syntax/test_data/parser/ok/0045_block_inner_attrs.rast delete mode 100644 crates/syntax/test_data/parser/ok/0045_block_inner_attrs.rs (limited to 'crates') diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 786fad6e1..d9294d93a 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs @@ -545,7 +545,7 @@ fn inner_attributes( _ => return None, } }; - let attrs = attrs.filter(|attr| attr.excl_token().is_some()); + let attrs = attrs.filter(|attr| attr.kind().is_inner()); let docs = docs.filter(|doc| doc.is_inner()); Some((attrs, docs)) } @@ -740,7 +740,7 @@ fn collect_attrs( let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) .map_or((None, None), |(attrs, docs)| (Some(attrs), Some(docs))); - let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none()); + let outer_attrs = owner.attrs().filter(|attr| attr.kind().is_outer()); let attrs = outer_attrs .chain(inner_attrs.into_iter().flatten()) .map(|attr| (attr.syntax().text_range().start(), Either::Left(attr))); diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index ae98dbd26..171099661 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -125,6 +125,18 @@ pub enum AttrKind { Outer, } +impl AttrKind { + /// Returns `true` if the attr_kind is [`Inner`]. + pub fn is_inner(&self) -> bool { + matches!(self, Self::Inner) + } + + /// Returns `true` if the attr_kind is [`Outer`]. + pub fn is_outer(&self) -> bool { + matches!(self, Self::Outer) + } +} + impl ast::Attr { pub fn as_simple_atom(&self) -> Option { if self.eq_token().is_some() || self.token_tree().is_some() { diff --git a/crates/syntax/src/validation/block.rs b/crates/syntax/src/validation/block.rs index ad9901468..40170014f 100644 --- a/crates/syntax/src/validation/block.rs +++ b/crates/syntax/src/validation/block.rs @@ -13,7 +13,7 @@ pub(crate) fn validate_block_expr(block: ast::BlockExpr, errors: &mut Vec {} } } - errors.extend(block.attrs().map(|attr| { + errors.extend(block.attrs().filter(|attr| attr.kind().is_inner()).map(|attr| { SyntaxError::new( "A block in this position cannot accept inner attributes", attr.syntax().text_range(), diff --git a/crates/syntax/test_data/parser/ok/0045_block_attrs.rast b/crates/syntax/test_data/parser/ok/0045_block_attrs.rast new file mode 100644 index 000000000..50ab52d32 --- /dev/null +++ b/crates/syntax/test_data/parser/ok/0045_block_attrs.rast @@ -0,0 +1,218 @@ +SOURCE_FILE@0..764 + FN@0..461 + FN_KW@0..2 "fn" + WHITESPACE@2..3 " " + NAME@3..8 + IDENT@3..8 "inner" + PARAM_LIST@8..10 + L_PAREN@8..9 "(" + R_PAREN@9..10 ")" + WHITESPACE@10..11 " " + BLOCK_EXPR@11..461 + L_CURLY@11..12 "{" + WHITESPACE@12..17 "\n " + ATTR@17..57 + POUND@17..18 "#" + BANG@18..19 "!" + L_BRACK@19..20 "[" + PATH@20..23 + PATH_SEGMENT@20..23 + NAME_REF@20..23 + IDENT@20..23 "doc" + TOKEN_TREE@23..56 + L_PAREN@23..24 "(" + STRING@24..55 "\"Inner attributes all ..." + R_PAREN@55..56 ")" + R_BRACK@56..57 "]" + WHITESPACE@57..62 "\n " + COMMENT@62..97 "//! As are ModuleDoc ..." + WHITESPACE@97..102 "\n " + EXPR_STMT@102..295 + BLOCK_EXPR@102..294 + L_CURLY@102..103 "{" + WHITESPACE@103..112 "\n " + ATTR@112..180 + POUND@112..113 "#" + BANG@113..114 "!" + L_BRACK@114..115 "[" + PATH@115..118 + PATH_SEGMENT@115..118 + NAME_REF@115..118 + IDENT@115..118 "doc" + TOKEN_TREE@118..179 + L_PAREN@118..119 "(" + STRING@119..178 "\"Inner attributes are ..." + R_PAREN@178..179 ")" + R_BRACK@179..180 "]" + WHITESPACE@180..189 "\n " + ATTR@189..244 + POUND@189..190 "#" + BANG@190..191 "!" + L_BRACK@191..192 "[" + PATH@192..195 + PATH_SEGMENT@192..195 + NAME_REF@192..195 + IDENT@192..195 "doc" + TOKEN_TREE@195..243 + L_PAREN@195..196 "(" + STRING@196..242 "\"Being validated is n ..." + R_PAREN@242..243 ")" + R_BRACK@243..244 "]" + WHITESPACE@244..253 "\n " + COMMENT@253..288 "//! As are ModuleDoc ..." + WHITESPACE@288..293 "\n " + R_CURLY@293..294 "}" + SEMICOLON@294..295 ";" + WHITESPACE@295..300 "\n " + BLOCK_EXPR@300..459 + L_CURLY@300..301 "{" + WHITESPACE@301..310 "\n " + ATTR@310..409 + POUND@310..311 "#" + BANG@311..312 "!" + L_BRACK@312..313 "[" + PATH@313..316 + PATH_SEGMENT@313..316 + NAME_REF@313..316 + IDENT@313..316 "doc" + TOKEN_TREE@316..408 + L_PAREN@316..317 "(" + STRING@317..407 "\"Inner attributes are ..." + R_PAREN@407..408 ")" + R_BRACK@408..409 "]" + WHITESPACE@409..418 "\n " + COMMENT@418..453 "//! As are ModuleDoc ..." + WHITESPACE@453..458 "\n " + R_CURLY@458..459 "}" + WHITESPACE@459..460 "\n" + R_CURLY@460..461 "}" + WHITESPACE@461..463 "\n\n" + FN@463..539 + FN_KW@463..465 "fn" + WHITESPACE@465..466 " " + NAME@466..471 + IDENT@466..471 "outer" + PARAM_LIST@471..473 + L_PAREN@471..472 "(" + R_PAREN@472..473 ")" + WHITESPACE@473..474 " " + BLOCK_EXPR@474..539 + L_CURLY@474..475 "{" + WHITESPACE@475..480 "\n " + LET_STMT@480..537 + LET_KW@480..483 "let" + WHITESPACE@483..484 " " + WILDCARD_PAT@484..485 + UNDERSCORE@484..485 "_" + WHITESPACE@485..486 " " + EQ@486..487 "=" + WHITESPACE@487..488 " " + BLOCK_EXPR@488..536 + ATTR@488..533 + POUND@488..489 "#" + L_BRACK@489..490 "[" + PATH@490..493 + PATH_SEGMENT@490..493 + NAME_REF@490..493 + IDENT@490..493 "doc" + TOKEN_TREE@493..532 + L_PAREN@493..494 "(" + STRING@494..531 "\"Outer attributes are ..." + R_PAREN@531..532 ")" + R_BRACK@532..533 "]" + WHITESPACE@533..534 " " + L_CURLY@534..535 "{" + R_CURLY@535..536 "}" + SEMICOLON@536..537 ";" + WHITESPACE@537..538 "\n" + R_CURLY@538..539 "}" + WHITESPACE@539..541 "\n\n" + COMMENT@541..601 "// https://github.com ..." + WHITESPACE@601..602 "\n" + IMPL@602..763 + IMPL_KW@602..606 "impl" + WHITESPACE@606..607 " " + PATH_TYPE@607..615 + PATH@607..615 + PATH_SEGMENT@607..615 + NAME_REF@607..615 + IDENT@607..615 "Whatever" + WHITESPACE@615..616 " " + ASSOC_ITEM_LIST@616..763 + L_CURLY@616..617 "{" + WHITESPACE@617..622 "\n " + FN@622..761 + FN_KW@622..624 "fn" + WHITESPACE@624..625 " " + NAME@625..636 + IDENT@625..636 "salsa_event" + PARAM_LIST@636..679 + L_PAREN@636..637 "(" + SELF_PARAM@637..642 + AMP@637..638 "&" + NAME@638..642 + SELF_KW@638..642 "self" + COMMA@642..643 "," + WHITESPACE@643..644 " " + PARAM@644..678 + IDENT_PAT@644..652 + NAME@644..652 + IDENT@644..652 "event_fn" + COLON@652..653 ":" + WHITESPACE@653..654 " " + IMPL_TRAIT_TYPE@654..678 + IMPL_KW@654..658 "impl" + WHITESPACE@658..659 " " + TYPE_BOUND_LIST@659..678 + TYPE_BOUND@659..678 + PATH_TYPE@659..678 + PATH@659..678 + PATH_SEGMENT@659..678 + NAME_REF@659..661 + IDENT@659..661 "Fn" + PARAM_LIST@661..663 + L_PAREN@661..662 "(" + R_PAREN@662..663 ")" + WHITESPACE@663..664 " " + RET_TYPE@664..678 + THIN_ARROW@664..666 "->" + WHITESPACE@666..667 " " + PATH_TYPE@667..678 + PATH@667..678 + PATH_SEGMENT@667..678 + NAME_REF@667..672 + IDENT@667..672 "Event" + GENERIC_ARG_LIST@672..678 + L_ANGLE@672..673 "<" + TYPE_ARG@673..677 + PATH_TYPE@673..677 + PATH@673..677 + PATH_SEGMENT@673..677 + NAME_REF@673..677 + IDENT@673..677 "Self" + R_ANGLE@677..678 ">" + R_PAREN@678..679 ")" + WHITESPACE@679..680 " " + BLOCK_EXPR@680..761 + L_CURLY@680..681 "{" + WHITESPACE@681..690 "\n " + ATTR@690..717 + POUND@690..691 "#" + BANG@691..692 "!" + L_BRACK@692..693 "[" + PATH@693..698 + PATH_SEGMENT@693..698 + NAME_REF@693..698 + IDENT@693..698 "allow" + TOKEN_TREE@698..716 + L_PAREN@698..699 "(" + IDENT@699..715 "unused_variables" + R_PAREN@715..716 ")" + R_BRACK@716..717 "]" + WHITESPACE@717..718 " " + COMMENT@718..755 "// this is `inner_at ..." + WHITESPACE@755..760 "\n " + R_CURLY@760..761 "}" + WHITESPACE@761..762 "\n" + R_CURLY@762..763 "}" + WHITESPACE@763..764 "\n" diff --git a/crates/syntax/test_data/parser/ok/0045_block_attrs.rs b/crates/syntax/test_data/parser/ok/0045_block_attrs.rs new file mode 100644 index 000000000..ed4593759 --- /dev/null +++ b/crates/syntax/test_data/parser/ok/0045_block_attrs.rs @@ -0,0 +1,24 @@ +fn inner() { + #![doc("Inner attributes allowed here")] + //! As are ModuleDoc style comments + { + #![doc("Inner attributes are allowed in blocks used as statements")] + #![doc("Being validated is not affected by duplcates")] + //! As are ModuleDoc style comments + }; + { + #![doc("Inner attributes are allowed in blocks when they are the last statement of another block")] + //! As are ModuleDoc style comments + } +} + +fn outer() { + let _ = #[doc("Outer attributes are always allowed")] {}; +} + +// https://github.com/rust-analyzer/rust-analyzer/issues/689 +impl Whatever { + fn salsa_event(&self, event_fn: impl Fn() -> Event) { + #![allow(unused_variables)] // this is `inner_attr` of the block + } +} diff --git a/crates/syntax/test_data/parser/ok/0045_block_inner_attrs.rast b/crates/syntax/test_data/parser/ok/0045_block_inner_attrs.rast deleted file mode 100644 index 6afed5f05..000000000 --- a/crates/syntax/test_data/parser/ok/0045_block_inner_attrs.rast +++ /dev/null @@ -1,178 +0,0 @@ -SOURCE_FILE@0..686 - FN@0..461 - FN_KW@0..2 "fn" - WHITESPACE@2..3 " " - NAME@3..8 - IDENT@3..8 "block" - PARAM_LIST@8..10 - L_PAREN@8..9 "(" - R_PAREN@9..10 ")" - WHITESPACE@10..11 " " - BLOCK_EXPR@11..461 - L_CURLY@11..12 "{" - WHITESPACE@12..17 "\n " - ATTR@17..57 - POUND@17..18 "#" - BANG@18..19 "!" - L_BRACK@19..20 "[" - PATH@20..23 - PATH_SEGMENT@20..23 - NAME_REF@20..23 - IDENT@20..23 "doc" - TOKEN_TREE@23..56 - L_PAREN@23..24 "(" - STRING@24..55 "\"Inner attributes all ..." - R_PAREN@55..56 ")" - R_BRACK@56..57 "]" - WHITESPACE@57..62 "\n " - COMMENT@62..97 "//! As are ModuleDoc ..." - WHITESPACE@97..102 "\n " - EXPR_STMT@102..295 - BLOCK_EXPR@102..294 - L_CURLY@102..103 "{" - WHITESPACE@103..112 "\n " - ATTR@112..180 - POUND@112..113 "#" - BANG@113..114 "!" - L_BRACK@114..115 "[" - PATH@115..118 - PATH_SEGMENT@115..118 - NAME_REF@115..118 - IDENT@115..118 "doc" - TOKEN_TREE@118..179 - L_PAREN@118..119 "(" - STRING@119..178 "\"Inner attributes are ..." - R_PAREN@178..179 ")" - R_BRACK@179..180 "]" - WHITESPACE@180..189 "\n " - ATTR@189..244 - POUND@189..190 "#" - BANG@190..191 "!" - L_BRACK@191..192 "[" - PATH@192..195 - PATH_SEGMENT@192..195 - NAME_REF@192..195 - IDENT@192..195 "doc" - TOKEN_TREE@195..243 - L_PAREN@195..196 "(" - STRING@196..242 "\"Being validated is n ..." - R_PAREN@242..243 ")" - R_BRACK@243..244 "]" - WHITESPACE@244..253 "\n " - COMMENT@253..288 "//! As are ModuleDoc ..." - WHITESPACE@288..293 "\n " - R_CURLY@293..294 "}" - SEMICOLON@294..295 ";" - WHITESPACE@295..300 "\n " - BLOCK_EXPR@300..459 - L_CURLY@300..301 "{" - WHITESPACE@301..310 "\n " - ATTR@310..409 - POUND@310..311 "#" - BANG@311..312 "!" - L_BRACK@312..313 "[" - PATH@313..316 - PATH_SEGMENT@313..316 - NAME_REF@313..316 - IDENT@313..316 "doc" - TOKEN_TREE@316..408 - L_PAREN@316..317 "(" - STRING@317..407 "\"Inner attributes are ..." - R_PAREN@407..408 ")" - R_BRACK@408..409 "]" - WHITESPACE@409..418 "\n " - COMMENT@418..453 "//! As are ModuleDoc ..." - WHITESPACE@453..458 "\n " - R_CURLY@458..459 "}" - WHITESPACE@459..460 "\n" - R_CURLY@460..461 "}" - WHITESPACE@461..463 "\n\n" - COMMENT@463..523 "// https://github.com ..." - WHITESPACE@523..524 "\n" - IMPL@524..685 - IMPL_KW@524..528 "impl" - WHITESPACE@528..529 " " - PATH_TYPE@529..537 - PATH@529..537 - PATH_SEGMENT@529..537 - NAME_REF@529..537 - IDENT@529..537 "Whatever" - WHITESPACE@537..538 " " - ASSOC_ITEM_LIST@538..685 - L_CURLY@538..539 "{" - WHITESPACE@539..544 "\n " - FN@544..683 - FN_KW@544..546 "fn" - WHITESPACE@546..547 " " - NAME@547..558 - IDENT@547..558 "salsa_event" - PARAM_LIST@558..601 - L_PAREN@558..559 "(" - SELF_PARAM@559..564 - AMP@559..560 "&" - NAME@560..564 - SELF_KW@560..564 "self" - COMMA@564..565 "," - WHITESPACE@565..566 " " - PARAM@566..600 - IDENT_PAT@566..574 - NAME@566..574 - IDENT@566..574 "event_fn" - COLON@574..575 ":" - WHITESPACE@575..576 " " - IMPL_TRAIT_TYPE@576..600 - IMPL_KW@576..580 "impl" - WHITESPACE@580..581 " " - TYPE_BOUND_LIST@581..600 - TYPE_BOUND@581..600 - PATH_TYPE@581..600 - PATH@581..600 - PATH_SEGMENT@581..600 - NAME_REF@581..583 - IDENT@581..583 "Fn" - PARAM_LIST@583..585 - L_PAREN@583..584 "(" - R_PAREN@584..585 ")" - WHITESPACE@585..586 " " - RET_TYPE@586..600 - THIN_ARROW@586..588 "->" - WHITESPACE@588..589 " " - PATH_TYPE@589..600 - PATH@589..600 - PATH_SEGMENT@589..600 - NAME_REF@589..594 - IDENT@589..594 "Event" - GENERIC_ARG_LIST@594..600 - L_ANGLE@594..595 "<" - TYPE_ARG@595..599 - PATH_TYPE@595..599 - PATH@595..599 - PATH_SEGMENT@595..599 - NAME_REF@595..599 - IDENT@595..599 "Self" - R_ANGLE@599..600 ">" - R_PAREN@600..601 ")" - WHITESPACE@601..602 " " - BLOCK_EXPR@602..683 - L_CURLY@602..603 "{" - WHITESPACE@603..612 "\n " - ATTR@612..639 - POUND@612..613 "#" - BANG@613..614 "!" - L_BRACK@614..615 "[" - PATH@615..620 - PATH_SEGMENT@615..620 - NAME_REF@615..620 - IDENT@615..620 "allow" - TOKEN_TREE@620..638 - L_PAREN@620..621 "(" - IDENT@621..637 "unused_variables" - R_PAREN@637..638 ")" - R_BRACK@638..639 "]" - WHITESPACE@639..640 " " - COMMENT@640..677 "// this is `inner_at ..." - WHITESPACE@677..682 "\n " - R_CURLY@682..683 "}" - WHITESPACE@683..684 "\n" - R_CURLY@684..685 "}" - WHITESPACE@685..686 "\n" diff --git a/crates/syntax/test_data/parser/ok/0045_block_inner_attrs.rs b/crates/syntax/test_data/parser/ok/0045_block_inner_attrs.rs deleted file mode 100644 index 88df8138e..000000000 --- a/crates/syntax/test_data/parser/ok/0045_block_inner_attrs.rs +++ /dev/null @@ -1,20 +0,0 @@ -fn block() { - #![doc("Inner attributes allowed here")] - //! As are ModuleDoc style comments - { - #![doc("Inner attributes are allowed in blocks used as statements")] - #![doc("Being validated is not affected by duplcates")] - //! As are ModuleDoc style comments - }; - { - #![doc("Inner attributes are allowed in blocks when they are the last statement of another block")] - //! As are ModuleDoc style comments - } -} - -// https://github.com/rust-analyzer/rust-analyzer/issues/689 -impl Whatever { - fn salsa_event(&self, event_fn: impl Fn() -> Event) { - #![allow(unused_variables)] // this is `inner_attr` of the block - } -} -- cgit v1.2.3