Комментарии
Lexer
LINE_COMMENT →
// ( ~[/ ! LF] | // ) ~LF*
| //
BLOCK_COMMENT →
/*
( ~[* !] | ** | BLOCK_COMMENT_OR_DOC )
( BLOCK_COMMENT_OR_DOC | ~*/ )*
*/
| /**/
| /***/
INNER_LINE_DOC →
//! ~[LF CR]*
INNER_BLOCK_DOC →
/*! ( BLOCK_COMMENT_OR_DOC | ~[*/ CR] )* */
OUTER_LINE_DOC →
/// ( ~/ ~[LF CR]* )?
OUTER_BLOCK_DOC →
/**
( ~* | BLOCK_COMMENT_OR_DOC )
( BLOCK_COMMENT_OR_DOC | ~[*/ CR] )*
*/
BLOCK_COMMENT_OR_DOC →
BLOCK_COMMENT
| OUTER_BLOCK_DOC
| INNER_BLOCK_DOC
Обычные комментарии (не документационные)
Комментарии следуют общему стилю C++: строчные (//) и
блочные (/* ... */) формы комментариев. Поддерживаются вложенные блочные комментарии.
Обычные комментарии интерпретируются как форма пробельных символов.
Комментарии документации
Строчные комментарии документации, начинающиеся ровно с трёх слешей (///), и блочные
комментарии документации (/** ... */), оба являющиеся внешними комментариями документации, интерпретируются как специальный
синтаксис для doc attributes.
То есть они эквивалентны написанию
#[doc="..."] вокруг тела комментария, т.е. /// Foo превращается в
#[doc="Foo"], а /** Bar */ превращается в #[doc="Bar"]. Следовательно, они должны
появляться перед тем, что принимает внешний атрибут.
Строчные комментарии, начинающиеся с //!, и блочные комментарии /*! ... */ — это
комментарии документации, которые применяются к родительскому элементу комментария, а не к элементу,
который следует за ним.
То есть они эквивалентны написанию #![doc="..."] вокруг
тела комментария. Комментарии //! обычно используются для документирования
модулей, занимающих исходный файл.
Символ U+000D (CR) не допускается в комментариях документации.
Note
Принято, чтобы комментарии документации содержали Markdown, как того ожидает
rustdoc. Однако синтаксис комментариев не учитывает внутреннюю разметку Markdown./** `glob = "*/*.rs";` */завершает комментарий при первом же*/, и оставшийся код вызовет синтаксическую ошибку. Это несколько ограничивает содержимое блочных комментариев документации по сравнению со строчными.
Note
Последовательность
U+000D(CR), сразу за которой следуетU+000A(LF), была бы ранее преобразована в одинU+000A(LF).
Примеры
#![allow(unused)] fn main() { //! Комментарий документации, применяемый к неявному анонимному модулю этого крейта pub mod outer_module { //! - Внутренний строчный комментарий документации //!! - Все ещё внутренний строчный комментарий документации (но с восклицательным знаком в начале) /*! - Внутренний блочный комментарий документации */ /*!! - Все ещё внутренний блочный комментарий документации (но с восклицательным знаком в начале) */ // - Просто комментарий /// - Внешний строчный комментарий документации (ровно 3 слеша) //// - Просто комментарий /* - Просто комментарий */ /** - Внешний блочный комментарий документации (ровно 2 звёздочки) */ /*** - Просто комментарий */ pub mod inner_module {} pub mod nested_comments { /* В Rust /* мы можем /* вкладывать комментарии */ */ */ // Все три типа блочных комментариев могут содержать или быть вложенными в // любой другой тип: /* /* */ /** */ /*! */ */ /*! /* */ /** */ /*! */ */ /** /* */ /** */ /*! */ */ pub mod dummy_item {} } pub mod degenerate_cases { // пустой внутренний строчный комментарий документации //! // пустой внутренний блочный комментарий документации /*!*/ // пустой строчный комментарий // // пустой внешний строчный комментарий документации /// // пустой блочный комментарий /**/ pub mod dummy_item {} // пустой блок с 2 звёздочками не является блоком документации, это блочный комментарий /***/ } /* Следующий пример не разрешён, потому что внешние комментарии документации требуют элемент, который получит документацию */ /// Где мой элемент? mod boo {} } }