}
+impl ast::AttrsOwner for Block {}
impl Block {
pub fn statements(&self) -> impl Iterator<Item = &Stmt> {
super::children(self)
options: [ "Expr" ],
collections: [
["statements", "Stmt"],
+ ],
+ traits: [
+ "AttrsOwner",
]
),
"ParamList": (
}
let m = p.start();
p.bump();
+ // This is checked by a validator
+ attributes::inner_attributes(p);
while !p.at(EOF) && !p.at(R_CURLY) {
match p.current() {
mod byte_string;
mod char;
mod string;
+mod block;
use crate::{
SourceFile, yellow::SyntaxError, AstNode,
.visit::<ast::ByteString, _>(self::byte_string::validate_byte_string_node)
.visit::<ast::Char, _>(self::char::validate_char_node)
.visit::<ast::String, _>(self::string::validate_string_node)
+ .visit::<ast::Block, _>(self::block::validate_block_node)
.accept(node);
}
errors
--- /dev/null
+use crate::{SyntaxKind::*,
+ ast::{self, AttrsOwner, AstNode},
+ yellow::{
+ SyntaxError,
+ SyntaxErrorKind::*,
+ },
+};
+
+pub(crate) fn validate_block_node(node: &ast::Block, errors: &mut Vec<SyntaxError>) {
+ if let Some(parent) = node.syntax().parent() {
+ match parent.kind() {
+ FN_DEF => return,
+ BLOCK_EXPR => match parent.parent().map(|v| v.kind()) {
+ Some(EXPR_STMT) | Some(BLOCK) => return,
+ _ => {}
+ },
+ _ => {}
+ }
+ }
+ errors.extend(
+ node.attrs()
+ .map(|attr| SyntaxError::new(InvalidBlockAttr, attr.syntax().range())),
+ )
+}
UnicodeEscapeOutOfRange,
UnclosedString,
InvalidSuffix,
+ InvalidBlockAttr,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
UnicodeEscapeOutOfRange => write!(f, "Unicode escape code should be at most 0x10FFFF"),
UnclosedString => write!(f, "Unclosed string literal"),
InvalidSuffix => write!(f, "Invalid literal suffix"),
+ InvalidBlockAttr => {
+ write!(f, "A block in this position cannot accept inner attributes")
+ }
ParseError(msg) => write!(f, "{}", msg.0),
}
}
--- /dev/null
+fn block() {
+ let inner = {
+ #![doc("Inner attributes not allowed here")]
+ //! Nor are ModuleDoc comments
+ };
+ if true {
+ #![doc("Nor here")]
+ #![doc("We error on each attr")]
+ //! Nor are ModuleDoc comments
+ }
+ while true {
+ #![doc("Nor here")]
+ //! Nor are ModuleDoc comments
+ }
+}
--- /dev/null
+SOURCE_FILE@[0; 350)
+ FN_DEF@[0; 349)
+ FN_KW@[0; 2)
+ 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@[11; 349)
+ L_CURLY@[11; 12)
+ WHITESPACE@[12; 17)
+ LET_STMT@[17; 129)
+ LET_KW@[17; 20)
+ WHITESPACE@[20; 21)
+ BIND_PAT@[21; 26)
+ NAME@[21; 26)
+ IDENT@[21; 26) "inner"
+ WHITESPACE@[26; 27)
+ EQ@[27; 28)
+ WHITESPACE@[28; 29)
+ BLOCK_EXPR@[29; 128)
+ BLOCK@[29; 128)
+ L_CURLY@[29; 30)
+ WHITESPACE@[30; 39)
+ err: `A block in this position cannot accept inner attributes`
+ ATTR@[39; 83)
+ POUND@[39; 40)
+ EXCL@[40; 41)
+ TOKEN_TREE@[41; 83)
+ L_BRACK@[41; 42)
+ IDENT@[42; 45) "doc"
+ TOKEN_TREE@[45; 82)
+ L_PAREN@[45; 46)
+ STRING@[46; 81)
+ R_PAREN@[81; 82)
+ R_BRACK@[82; 83)
+ WHITESPACE@[83; 92)
+ COMMENT@[92; 122)
+ WHITESPACE@[122; 127)
+ R_CURLY@[127; 128)
+ SEMI@[128; 129)
+ WHITESPACE@[129; 134)
+ EXPR_STMT@[134; 257)
+ IF_EXPR@[134; 257)
+ IF_KW@[134; 136)
+ WHITESPACE@[136; 137)
+ CONDITION@[137; 141)
+ LITERAL@[137; 141)
+ TRUE_KW@[137; 141)
+ WHITESPACE@[141; 142)
+ BLOCK@[142; 257)
+ L_CURLY@[142; 143)
+ WHITESPACE@[143; 152)
+ err: `A block in this position cannot accept inner attributes`
+ ATTR@[152; 171)
+ POUND@[152; 153)
+ EXCL@[153; 154)
+ TOKEN_TREE@[154; 171)
+ L_BRACK@[154; 155)
+ IDENT@[155; 158) "doc"
+ TOKEN_TREE@[158; 170)
+ L_PAREN@[158; 159)
+ STRING@[159; 169)
+ R_PAREN@[169; 170)
+ R_BRACK@[170; 171)
+ WHITESPACE@[171; 180)
+ err: `A block in this position cannot accept inner attributes`
+ ATTR@[180; 212)
+ POUND@[180; 181)
+ EXCL@[181; 182)
+ TOKEN_TREE@[182; 212)
+ L_BRACK@[182; 183)
+ IDENT@[183; 186) "doc"
+ TOKEN_TREE@[186; 211)
+ L_PAREN@[186; 187)
+ STRING@[187; 210)
+ R_PAREN@[210; 211)
+ R_BRACK@[211; 212)
+ WHITESPACE@[212; 221)
+ COMMENT@[221; 251)
+ WHITESPACE@[251; 256)
+ R_CURLY@[256; 257)
+ WHITESPACE@[257; 262)
+ WHILE_EXPR@[262; 347)
+ WHILE_KW@[262; 267)
+ WHITESPACE@[267; 268)
+ CONDITION@[268; 272)
+ LITERAL@[268; 272)
+ TRUE_KW@[268; 272)
+ WHITESPACE@[272; 273)
+ BLOCK@[273; 347)
+ L_CURLY@[273; 274)
+ WHITESPACE@[274; 283)
+ err: `A block in this position cannot accept inner attributes`
+ ATTR@[283; 302)
+ POUND@[283; 284)
+ EXCL@[284; 285)
+ TOKEN_TREE@[285; 302)
+ L_BRACK@[285; 286)
+ IDENT@[286; 289) "doc"
+ TOKEN_TREE@[289; 301)
+ L_PAREN@[289; 290)
+ STRING@[290; 300)
+ R_PAREN@[300; 301)
+ R_BRACK@[301; 302)
+ WHITESPACE@[302; 311)
+ COMMENT@[311; 341)
+ WHITESPACE@[341; 346)
+ R_CURLY@[346; 347)
+ WHITESPACE@[347; 348)
+ R_CURLY@[348; 349)
+ WHITESPACE@[349; 350)
--- /dev/null
+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<Self>) {
+ #![allow(unused_variables)] // this is `inner_attr` of the block
+ }
+}
--- /dev/null
+SOURCE_FILE@[0; 686)
+ FN_DEF@[0; 461)
+ FN_KW@[0; 2)
+ 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@[11; 461)
+ L_CURLY@[11; 12)
+ WHITESPACE@[12; 17)
+ ATTR@[17; 57)
+ POUND@[17; 18)
+ EXCL@[18; 19)
+ TOKEN_TREE@[19; 57)
+ L_BRACK@[19; 20)
+ IDENT@[20; 23) "doc"
+ TOKEN_TREE@[23; 56)
+ L_PAREN@[23; 24)
+ STRING@[24; 55)
+ R_PAREN@[55; 56)
+ R_BRACK@[56; 57)
+ WHITESPACE@[57; 62)
+ COMMENT@[62; 97)
+ WHITESPACE@[97; 102)
+ EXPR_STMT@[102; 295)
+ BLOCK_EXPR@[102; 294)
+ BLOCK@[102; 294)
+ L_CURLY@[102; 103)
+ WHITESPACE@[103; 112)
+ ATTR@[112; 180)
+ POUND@[112; 113)
+ EXCL@[113; 114)
+ TOKEN_TREE@[114; 180)
+ L_BRACK@[114; 115)
+ IDENT@[115; 118) "doc"
+ TOKEN_TREE@[118; 179)
+ L_PAREN@[118; 119)
+ STRING@[119; 178)
+ R_PAREN@[178; 179)
+ R_BRACK@[179; 180)
+ WHITESPACE@[180; 189)
+ ATTR@[189; 244)
+ POUND@[189; 190)
+ EXCL@[190; 191)
+ TOKEN_TREE@[191; 244)
+ L_BRACK@[191; 192)
+ IDENT@[192; 195) "doc"
+ TOKEN_TREE@[195; 243)
+ L_PAREN@[195; 196)
+ STRING@[196; 242)
+ R_PAREN@[242; 243)
+ R_BRACK@[243; 244)
+ WHITESPACE@[244; 253)
+ COMMENT@[253; 288)
+ WHITESPACE@[288; 293)
+ R_CURLY@[293; 294)
+ SEMI@[294; 295)
+ WHITESPACE@[295; 300)
+ BLOCK_EXPR@[300; 459)
+ BLOCK@[300; 459)
+ L_CURLY@[300; 301)
+ WHITESPACE@[301; 310)
+ ATTR@[310; 409)
+ POUND@[310; 311)
+ EXCL@[311; 312)
+ TOKEN_TREE@[312; 409)
+ L_BRACK@[312; 313)
+ IDENT@[313; 316) "doc"
+ TOKEN_TREE@[316; 408)
+ L_PAREN@[316; 317)
+ STRING@[317; 407)
+ R_PAREN@[407; 408)
+ R_BRACK@[408; 409)
+ WHITESPACE@[409; 418)
+ COMMENT@[418; 453)
+ WHITESPACE@[453; 458)
+ R_CURLY@[458; 459)
+ WHITESPACE@[459; 460)
+ R_CURLY@[460; 461)
+ WHITESPACE@[461; 463)
+ COMMENT@[463; 523)
+ WHITESPACE@[523; 524)
+ IMPL_BLOCK@[524; 685)
+ IMPL_KW@[524; 528)
+ 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)
+ ITEM_LIST@[538; 685)
+ L_CURLY@[538; 539)
+ WHITESPACE@[539; 544)
+ FN_DEF@[544; 683)
+ FN_KW@[544; 546)
+ 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)
+ SELF_KW@[560; 564)
+ COMMA@[564; 565)
+ WHITESPACE@[565; 566)
+ PARAM@[566; 600)
+ BIND_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)
+ WHITESPACE@[580; 581)
+ 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"
+ TYPE_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@[602; 683)
+ L_CURLY@[602; 603)
+ WHITESPACE@[603; 612)
+ ATTR@[612; 639)
+ POUND@[612; 613)
+ EXCL@[613; 614)
+ TOKEN_TREE@[614; 639)
+ L_BRACK@[614; 615)
+ 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)
+ WHITESPACE@[677; 682)
+ R_CURLY@[682; 683)
+ WHITESPACE@[683; 684)
+ R_CURLY@[684; 685)
+ WHITESPACE@[685; 686)