From: Philip Herron <philip.herron@embecosm.com>
To: gcc-rust@gcc.gnu.org
Subject: Re: [PATCH] Handle doc comment strings in lexer and parser
Date: Mon, 12 Jul 2021 09:09:09 +0100 [thread overview]
Message-ID: <fa073e0b-5601-e0be-f022-96839e191c0c@embecosm.com> (raw)
In-Reply-To: <20210711201018.389798-1-mark@klomp.org>
[-- Attachment #1.1: Type: text/plain, Size: 26382 bytes --]
On 11/07/2021 21:10, Mark Wielaard wrote:
> Remove (unused) comment related tokens and replace them with
> INNER_DOC_COMMENT and OUTER_DOC_COMMENT tokens, which keep the comment
> text as a string. These can be constructed with the new
> make_inner_doc_comment and make_outer_doc_comment methods.
>
> Make sure to not confuse doc strings with normal comments in the lexer
> when detecting shebang lines. Both single line //! and /*! */ blocks
> are turned into INNER_DOC_COMMENT tokens. And both single line /// and
> /** */ blocks are turned into OUTER_DOC_COMMENT tokens.
>
> Also fixes some issues with cr/lf line endings and keeping the line
> map correct when seeing \n in a comment.
>
> In the parser handle INNER_DOC_COMMENT and OUTER_DOC_COMMENTS where
> inner (#[]) and outer (#![]) attributes are handled. Add a method
> parse_doc_comment which turns the tokens into an "doc" Attribute with
> the string as literal expression.
>
> Add get_locus method to Attribute class for better error reporting.
>
> Tests are added for correctly placed and formatted doc strings, with
> or without cr/lf line endings. Incorrect formatted (isolated CRs) doc
> strings and badly placed inner doc strings. No tests add handling of
> the actual doc attributes yet. These could be tested once we add
> support for the #![warn(missing_docs)] attribute.
> ---
> gcc/rust/ast/rust-ast.h | 2 +
> gcc/rust/lex/rust-lex.cc | 214 ++++++++++++++++--
> gcc/rust/lex/rust-token.h | 25 +-
> gcc/rust/parse/rust-parse-impl.h | 60 ++++-
> gcc/rust/parse/rust-parse.h | 1 +
> gcc/testsuite/rust/compile/bad_inner_doc.rs | 15 ++
> .../compile/doc_isolated_cr_block_comment.rs | 3 +
> .../doc_isolated_cr_inner_block_comment.rs | 5 +
> .../doc_isolated_cr_inner_line_comment.rs | 5 +
> .../compile/doc_isolated_cr_line_comment.rs | 3 +
> .../torture/all_doc_comment_line_blocks.rs | 47 ++++
> .../all_doc_comment_line_blocks_crlf.rs | 47 ++++
> .../torture/isolated_cr_block_comment.rs | 2 +
> .../torture/isolated_cr_line_comment.rs | 2 +
> 14 files changed, 401 insertions(+), 30 deletions(-)
> create mode 100644 gcc/testsuite/rust/compile/bad_inner_doc.rs
> create mode 100644 gcc/testsuite/rust/compile/doc_isolated_cr_block_comment.rs
> create mode 100644 gcc/testsuite/rust/compile/doc_isolated_cr_inner_block_comment.rs
> create mode 100644 gcc/testsuite/rust/compile/doc_isolated_cr_inner_line_comment.rs
> create mode 100644 gcc/testsuite/rust/compile/doc_isolated_cr_line_comment.rs
> create mode 100644 gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks.rs
> create mode 100644 gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks_crlf.rs
> create mode 100644 gcc/testsuite/rust/compile/torture/isolated_cr_block_comment.rs
> create mode 100644 gcc/testsuite/rust/compile/torture/isolated_cr_line_comment.rs
>
> diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
> index 75b08f8aa66..3e3e185b9b5 100644
> --- a/gcc/rust/ast/rust-ast.h
> +++ b/gcc/rust/ast/rust-ast.h
> @@ -455,6 +455,8 @@ public:
> // Returns whether the attribute is considered an "empty" attribute.
> bool is_empty () const { return attr_input == nullptr && path.is_empty (); }
>
> + Location get_locus () const { return locus; }
> +
> /* e.g.:
> #![crate_type = "lib"]
> #[test]
> diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
> index 617dd69a080..0b8a8eae651 100644
> --- a/gcc/rust/lex/rust-lex.cc
> +++ b/gcc/rust/lex/rust-lex.cc
> @@ -265,9 +265,16 @@ Lexer::build_token ()
> int next_char = peek_input (n);
> if (is_whitespace (next_char))
> n++;
> - else if (next_char == '/' && peek_input (n + 1) == '/')
> + else if ((next_char == '/' && peek_input (n + 1) == '/'
> + && peek_input (n + 2) != '!'
> + && peek_input (n + 2) != '/')
> + || (next_char == '/' && peek_input (n + 1) == '/'
> + && peek_input (n + 2) == '/'
> + && peek_input (n + 3) == '/'))
> {
> + // two // or four ////
> // A single line comment
> + // (but not an inner or outer doc comment)
> n += 2;
> next_char = peek_input (n);
> while (next_char != '\n' && next_char != EOF)
> @@ -278,9 +285,30 @@ Lexer::build_token ()
> if (next_char == '\n')
> n++;
> }
> - else if (next_char == '/' && peek_input (n + 1) == '*')
> + else if (next_char == '/' && peek_input (n + 1) == '*'
> + && peek_input (n + 2) == '*'
> + && peek_input (n + 3) == '/')
> {
> + /**/
> + n += 4;
> + }
> + else if (next_char == '/' && peek_input (n + 1) == '*'
> + && peek_input (n + 2) == '*' && peek_input (n + 3) == '*'
> + && peek_input (n + 4) == '/')
> + {
> + /***/
> + n += 5;
> + }
> + else if ((next_char == '/' && peek_input (n + 1) == '*'
> + && peek_input (n + 2) != '*'
> + && peek_input (n + 2) != '!')
> + || (next_char == '/' && peek_input (n + 1) == '*'
> + && peek_input (n + 2) == '*'
> + && peek_input (n + 3) == '*'))
> + {
> + // one /* or three /***
> // Start of a block comment
> + // (but not an inner or outer doc comment)
> n += 2;
> int level = 1;
> while (level > 0)
> @@ -339,6 +367,9 @@ Lexer::build_token ()
> // tell line_table that new line starts
> line_map->start_line (current_line, max_column_hint);
> continue;
> + case '\r': // cr
> + // Ignore, we expect a newline (lf) soon.
> + continue;
> case ' ': // space
> current_column++;
> continue;
> @@ -445,11 +476,14 @@ Lexer::build_token ()
>
> return Token::make (DIV_EQ, loc);
> }
> - else if (peek_input () == '/')
> + else if ((peek_input () == '/' && peek_input (1) != '!'
> + && peek_input (1) != '/')
> + || (peek_input () == '/' && peek_input (1) == '/'
> + && peek_input (2) == '/'))
> {
> - // TODO: single-line doc comments
> -
> + // two // or four ////
> // single line comment
> + // (but not an inner or outer doc comment)
> skip_input ();
> current_column += 2;
>
> @@ -461,23 +495,85 @@ Lexer::build_token ()
> current_char = peek_input ();
> }
> continue;
> - break;
> }
> - else if (peek_input () == '*')
> + else if (peek_input () == '/'
> + && (peek_input (1) == '!' || peek_input (1) == '/'))
> {
> + /* single line doc comment, inner or outer. */
> + bool is_inner = peek_input (1) == '!';
> + skip_input (1);
> + current_column += 3;
> +
> + std::string str;
> + str.reserve (32);
> + current_char = peek_input ();
> + while (current_char != '\n')
> + {
> + skip_input ();
> + if (current_char == '\r')
> + {
> + char next_char = peek_input ();
> + if (next_char == '\n')
> + {
> + current_char = '\n';
> + break;
> + }
> + rust_error_at (
> + loc, "Isolated CR %<\\r%> not allowed in doc comment");
> + current_char = next_char;
> + continue;
> + }
> + if (current_char == EOF)
> + {
> + rust_error_at (
> + loc, "unexpected EOF while looking for end of comment");
> + break;
> + }
> + str += current_char;
> + current_char = peek_input ();
> + }
> + skip_input ();
> + current_line++;
> + current_column = 1;
> + // tell line_table that new line starts
> + line_map->start_line (current_line, max_column_hint);
> +
> + str.shrink_to_fit ();
> + if (is_inner)
> + return Token::make_inner_doc_comment (loc, std::move (str));
> + else
> + return Token::make_outer_doc_comment (loc, std::move (str));
> + }
> + else if (peek_input () == '*' && peek_input (1) == '*'
> + && peek_input (2) == '/')
> + {
> + /**/
> + skip_input (2);
> + current_column += 4;
> + continue;
> + }
> + else if (peek_input () == '*' && peek_input (1) == '*'
> + && peek_input (2) == '*' && peek_input (3) == '/')
> + {
> + /***/
> + skip_input (3);
> + current_column += 5;
> + continue;
> + }
> + else if ((peek_input () == '*' && peek_input (1) != '!'
> + && peek_input (1) != '*')
> + || (peek_input () == '*' && peek_input (1) == '*'
> + && peek_input (2) == '*'))
> + {
> + // one /* or three /***
> // block comment
> + // (but not an inner or outer doc comment)
> skip_input ();
> current_column += 2;
>
> - // TODO: block doc comments
> -
> - current_char = peek_input ();
> -
> int level = 1;
> while (level > 0)
> {
> - skip_input ();
> - current_column++; // for error-handling
> current_char = peek_input ();
>
> if (current_char == EOF)
> @@ -496,6 +592,7 @@ Lexer::build_token ()
> current_column += 2;
>
> level += 1;
> + continue;
> }
>
> // ignore until */ is found
> @@ -505,16 +602,101 @@ Lexer::build_token ()
> skip_input (1);
>
> current_column += 2;
> - // should only break inner loop here - seems to do so
> - // break;
>
> level -= 1;
> + continue;
> }
> +
> + if (current_char == '\n')
> + {
> + skip_input ();
> + current_line++;
> + current_column = 1;
> + // tell line_table that new line starts
> + line_map->start_line (current_line, max_column_hint);
> + continue;
> + }
> +
> + skip_input ();
> + current_column++;
> }
>
> // refresh new token
> continue;
> - break;
> + }
> + else if (peek_input () == '*'
> + && (peek_input (1) == '!' || peek_input (1) == '*'))
> + {
> + // block doc comment, inner /*! or outer /**
> + bool is_inner = peek_input (1) == '!';
> + skip_input (1);
> + current_column += 3;
> +
> + std::string str;
> + str.reserve (96);
> +
> + int level = 1;
> + while (level > 0)
> + {
> + current_char = peek_input ();
> +
> + if (current_char == EOF)
> + {
> + rust_error_at (
> + loc, "unexpected EOF while looking for end of comment");
> + break;
> + }
> +
> + // if /* found
> + if (current_char == '/' && peek_input (1) == '*')
> + {
> + // skip /* characters
> + skip_input (1);
> + current_column += 2;
> +
> + level += 1;
> + str += "/*";
> + continue;
> + }
> +
> + // ignore until */ is found
> + if (current_char == '*' && peek_input (1) == '/')
> + {
> + // skip */ characters
> + skip_input (1);
> + current_column += 2;
> +
> + level -= 1;
> + if (level > 0)
> + str += "*/";
> + continue;
> + }
> +
> + if (current_char == '\r' && peek_input (1) != '\n')
> + rust_error_at (
> + loc, "Isolated CR %<\\r%> not allowed in doc comment");
> +
> + if (current_char == '\n')
> + {
> + skip_input ();
> + current_line++;
> + current_column = 1;
> + // tell line_table that new line starts
> + line_map->start_line (current_line, max_column_hint);
> + str += '\n';
> + continue;
> + }
> +
> + str += current_char;
> + skip_input ();
> + current_column++;
> + }
> +
> + str.shrink_to_fit ();
> + if (is_inner)
> + return Token::make_inner_doc_comment (loc, std::move (str));
> + else
> + return Token::make_outer_doc_comment (loc, std::move (str));
> }
> else
> {
> diff --git a/gcc/rust/lex/rust-token.h b/gcc/rust/lex/rust-token.h
> index 771910119b7..1c397c839fd 100644
> --- a/gcc/rust/lex/rust-token.h
> +++ b/gcc/rust/lex/rust-token.h
> @@ -151,15 +151,10 @@ enum PrimitiveCoreType
> RS_TOKEN (RIGHT_SQUARE, "]") \
> /* Macros */ \
> RS_TOKEN (DOLLAR_SIGN, "$") \
> - /* Comments */ \
> - RS_TOKEN (LINE_COMMENT, "//") \
> - RS_TOKEN (INNER_LINE_DOC, "//!") \
> - RS_TOKEN (OUTER_LINE_DOC, "///") \
> - RS_TOKEN (BLOCK_COMMENT_START, "/*") \
> - RS_TOKEN (BLOCK_COMMENT_END, "*/") \
> - RS_TOKEN (INNER_BLOCK_DOC_START, "/*!") \
> - RS_TOKEN (OUTER_BLOCK_DOC_START, \
> - "/**") /* have "weak" union and 'static keywords? */ \
> + /* Doc Comments */ \
> + RS_TOKEN (INNER_DOC_COMMENT, "#![doc]") \
> + RS_TOKEN (OUTER_DOC_COMMENT, "#[doc]") \
> + /* have "weak" union and 'static keywords? */ \
> \
> RS_TOKEN_KEYWORD (ABSTRACT, "abstract") /* unused */ \
> RS_TOKEN_KEYWORD (AS, "as") \
> @@ -368,6 +363,18 @@ public:
> return TokenPtr (new Token (BYTE_STRING_LITERAL, locus, std::move (str)));
> }
>
> + // Makes and returns a new TokenPtr of type INNER_DOC_COMMENT.
> + static TokenPtr make_inner_doc_comment (Location locus, std::string &&str)
> + {
> + return TokenPtr (new Token (INNER_DOC_COMMENT, locus, std::move (str)));
> + }
> +
> + // Makes and returns a new TokenPtr of type OUTER_DOC_COMMENT.
> + static TokenPtr make_outer_doc_comment (Location locus, std::string &&str)
> + {
> + return TokenPtr (new Token (OUTER_DOC_COMMENT, locus, std::move (str)));
> + }
> +
> // Makes and returns a new TokenPtr of type LIFETIME.
> static TokenPtr make_lifetime (Location locus, std::string &&str)
> {
> diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
> index a8597fa401e..eedc76db43e 100644
> --- a/gcc/rust/parse/rust-parse-impl.h
> +++ b/gcc/rust/parse/rust-parse-impl.h
> @@ -434,8 +434,9 @@ Parser<ManagedTokenSource>::parse_inner_attributes ()
> AST::AttrVec inner_attributes;
>
> // only try to parse it if it starts with "#!" not only "#"
> - while (lexer.peek_token ()->get_id () == HASH
> - && lexer.peek_token (1)->get_id () == EXCLAM)
> + while ((lexer.peek_token ()->get_id () == HASH
> + && lexer.peek_token (1)->get_id () == EXCLAM)
> + || lexer.peek_token ()->get_id () == INNER_DOC_COMMENT)
> {
> AST::Attribute inner_attr = parse_inner_attribute ();
>
> @@ -457,11 +458,33 @@ Parser<ManagedTokenSource>::parse_inner_attributes ()
> return inner_attributes;
> }
>
> +// Parse a inner or outer doc comment into an doc attribute
> +template <typename ManagedTokenSource>
> +AST::Attribute
> +Parser<ManagedTokenSource>::parse_doc_comment ()
> +{
> + const_TokenPtr token = lexer.peek_token ();
> + Location locus = token->get_locus ();
> + AST::SimplePathSegment segment ("doc", locus);
> + std::vector<AST::SimplePathSegment> segments;
> + segments.push_back (std::move (segment));
> + AST::SimplePath attr_path (std::move (segments), false, locus);
> + AST::LiteralExpr lit_expr (token->get_str (), AST::Literal::STRING,
> + PrimitiveCoreType::CORETYPE_STR, {}, locus);
> + std::unique_ptr<AST::AttrInput> attr_input (
> + new AST::AttrInputLiteral (std::move (lit_expr)));
> + lexer.skip_token ();
> + return AST::Attribute (std::move (attr_path), std::move (attr_input), locus);
> +}
> +
> // Parse a single inner attribute.
> template <typename ManagedTokenSource>
> AST::Attribute
> Parser<ManagedTokenSource>::parse_inner_attribute ()
> {
> + if (lexer.peek_token ()->get_id () == INNER_DOC_COMMENT)
> + return parse_doc_comment ();
> +
> if (lexer.peek_token ()->get_id () != HASH)
> {
> Error error (lexer.peek_token ()->get_locus (),
> @@ -1019,7 +1042,15 @@ Parser<ManagedTokenSource>::parse_item (bool called_from_statement)
> switch (t->get_id ())
> {
> case END_OF_FILE:
> - // not necessarily an error
> + // not necessarily an error, unless we just read outer
> + // attributes which needs to be attached
> + if (!outer_attrs.empty ())
> + {
> + Rust::AST::Attribute attr = outer_attrs.back ();
> + Error error (attr.get_locus (),
> + "expected item after outer attribute or doc comment");
> + add_error (std::move (error));
> + }
> return nullptr;
> case PUB:
> case MOD:
> @@ -1091,7 +1122,11 @@ Parser<ManagedTokenSource>::parse_outer_attributes ()
> {
> AST::AttrVec outer_attributes;
>
> - while (lexer.peek_token ()->get_id () == HASH)
> + while (lexer.peek_token ()->get_id ()
> + == HASH /* Can also be #!, which catches errors. */
> + || lexer.peek_token ()->get_id () == OUTER_DOC_COMMENT
> + || lexer.peek_token ()->get_id ()
> + == INNER_DOC_COMMENT) /* For error handling. */
> {
> AST::Attribute outer_attr = parse_outer_attribute ();
>
> @@ -1121,6 +1156,20 @@ template <typename ManagedTokenSource>
> AST::Attribute
> Parser<ManagedTokenSource>::parse_outer_attribute ()
> {
> + if (lexer.peek_token ()->get_id () == OUTER_DOC_COMMENT)
> + return parse_doc_comment ();
> +
> + if (lexer.peek_token ()->get_id () == INNER_DOC_COMMENT)
> + {
> + Error error (
> + lexer.peek_token ()->get_locus (),
> + "inner doc (%<//!%> or %</*!%>) only allowed at start of item "
> + "and before any outer attribute or doc (%<#[%>, %<///%> or %</**%>)");
> + add_error (std::move (error));
> + lexer.skip_token ();
> + return AST::Attribute::create_empty ();
> + }
> +
> /* OuterAttribute -> '#' '[' Attr ']' */
>
> if (lexer.peek_token ()->get_id () != HASH)
> @@ -1134,12 +1183,13 @@ Parser<ManagedTokenSource>::parse_outer_attribute ()
> if (id == EXCLAM)
> {
> // this is inner attribute syntax, so throw error
> + // inner attributes were either already parsed or not allowed here.
> Error error (
> lexer.peek_token ()->get_locus (),
> "token %<!%> found, indicating inner attribute definition. Inner "
> "attributes are not possible at this location");
> add_error (std::move (error));
> - } // TODO: are there any cases where this wouldn't be an error?
> + }
> return AST::Attribute::create_empty ();
> }
>
> diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
> index bde2613f03d..1cd85eae8c2 100644
> --- a/gcc/rust/parse/rust-parse.h
> +++ b/gcc/rust/parse/rust-parse.h
> @@ -107,6 +107,7 @@ private:
> AST::Attribute parse_outer_attribute ();
> AST::Attribute parse_attribute_body ();
> std::unique_ptr<AST::AttrInput> parse_attr_input ();
> + AST::Attribute parse_doc_comment ();
>
> // Path-related
> AST::SimplePath parse_simple_path ();
> diff --git a/gcc/testsuite/rust/compile/bad_inner_doc.rs b/gcc/testsuite/rust/compile/bad_inner_doc.rs
> new file mode 100644
> index 00000000000..cfd166ce3ec
> --- /dev/null
> +++ b/gcc/testsuite/rust/compile/bad_inner_doc.rs
> @@ -0,0 +1,15 @@
> +pub fn main ()
> +{
> + //! inner doc allowed
> + let _x = 42;
> + // { dg-error "inner doc" "" { target *-*-* } .+1 }
> + //! inner doc disallowed
> + mod module
> + {
> + /*! inner doc allowed */
> + /// outer doc allowed
> + // { dg-error "inner doc" "" { target *-*-* } .+1 }
> + /*! but inner doc not here */
> + mod x { }
> + }
> +}
> diff --git a/gcc/testsuite/rust/compile/doc_isolated_cr_block_comment.rs b/gcc/testsuite/rust/compile/doc_isolated_cr_block_comment.rs
> new file mode 100644
> index 00000000000..0ada77f69cf
> --- /dev/null
> +++ b/gcc/testsuite/rust/compile/doc_isolated_cr_block_comment.rs
> @@ -0,0 +1,3 @@
> +// { dg-error "Isolated CR" "" { target *-*-* } .+1 }
> +/** doc cr
> comment */
> +pub fn main () { }
> diff --git a/gcc/testsuite/rust/compile/doc_isolated_cr_inner_block_comment.rs b/gcc/testsuite/rust/compile/doc_isolated_cr_inner_block_comment.rs
> new file mode 100644
> index 00000000000..7db35341bee
> --- /dev/null
> +++ b/gcc/testsuite/rust/compile/doc_isolated_cr_inner_block_comment.rs
> @@ -0,0 +1,5 @@
> +pub fn main ()
> +{
> +// { dg-error "Isolated CR" "" { target *-*-* } .+1 }
> + /*! doc cr
> comment */
> +}
> diff --git a/gcc/testsuite/rust/compile/doc_isolated_cr_inner_line_comment.rs b/gcc/testsuite/rust/compile/doc_isolated_cr_inner_line_comment.rs
> new file mode 100644
> index 00000000000..d75da75e218
> --- /dev/null
> +++ b/gcc/testsuite/rust/compile/doc_isolated_cr_inner_line_comment.rs
> @@ -0,0 +1,5 @@
> +pub fn main ()
> +{
> +// { dg-error "Isolated CR" "" { target *-*-* } .+1 }
> + //! doc cr
> comment
> +}
> diff --git a/gcc/testsuite/rust/compile/doc_isolated_cr_line_comment.rs b/gcc/testsuite/rust/compile/doc_isolated_cr_line_comment.rs
> new file mode 100644
> index 00000000000..7b6ef989c30
> --- /dev/null
> +++ b/gcc/testsuite/rust/compile/doc_isolated_cr_line_comment.rs
> @@ -0,0 +1,3 @@
> +// { dg-error "Isolated CR" "" { target *-*-* } .+1 }
> +/// doc cr
> comment
> +pub fn main () { }
> diff --git a/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks.rs b/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks.rs
> new file mode 100644
> index 00000000000..ab38ac69610
> --- /dev/null
> +++ b/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks.rs
> @@ -0,0 +1,47 @@
> +// comment line not a doc
> +/* comment block not a doc */
> +
> +//! inner line comment for most outer crate
> +/*! inner block comment for most outer crate */
> +
> +// comment line not a doc
> +/* comment block not a doc */
> +
> +/// outer doc line for module
> +/** outer doc block for module */
> +pub mod module
> +{
> + //! inner line doc
> + //!! inner line doc!
> + /*! inner block doc */
> + /*!! inner block doc! */
> +
> + // line comment
> + /// outer line doc
> + //// line comment
> +
> + /* block comment */
> + /** outer block doc */
> + /*** block comment */
> +
> + mod block_doc_comments
> + {
> + /* /* */ /** */ /*! */ */
> + /*! /* */ /** */ /*! */ */
> + /** /* */ /** */ /*! */ */
> + mod item { }
> + }
> +
> + pub mod empty
> + {
> + //!
> + /*!*/
> + //
> +
> + ///
> + mod doc { }
> + /**/
> + /***/
> + }
> +}
> +pub fn main () { }
> diff --git a/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks_crlf.rs b/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks_crlf.rs
> new file mode 100644
> index 00000000000..3ea2cd01c8c
> --- /dev/null
> +++ b/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks_crlf.rs
> @@ -0,0 +1,47 @@
> +// comment line not a doc
> +/* comment block not a doc */
> +
> +//! inner line comment for most outer crate
> +/*! inner block comment for most outer crate */
> +
> +// comment line not a doc
> +/* comment block not a doc */
> +
> +/// outer doc line for module
> +/** outer doc block for module */
> +pub mod module
> +{
> + //! inner line doc
> + //!! inner line doc!
> + /*! inner block doc */
> + /*!! inner block doc! */
> +
> + // line comment
> + /// outer line doc
> + //// line comment
> +
> + /* block comment */
> + /** outer block doc */
> + /*** block comment */
> +
> + mod block_doc_comments
> + {
> + /* /* */ /** */ /*! */ */
> + /*! /* */ /** */ /*! */ */
> + /** /* */ /** */ /*! */ */
> + mod item { }
> + }
> +
> + pub mod empty
> + {
> + //!
> + /*!*/
> + //
> +
> + ///
> + mod doc { }
> + /**/
> + /***/
> + }
> +}
> +pub fn main () { }
> diff --git a/gcc/testsuite/rust/compile/torture/isolated_cr_block_comment.rs b/gcc/testsuite/rust/compile/torture/isolated_cr_block_comment.rs
> new file mode 100644
> index 00000000000..9a1e090f330
> --- /dev/null
> +++ b/gcc/testsuite/rust/compile/torture/isolated_cr_block_comment.rs
> @@ -0,0 +1,2 @@
> +/* comment cr
> is allowed */
> +pub fn main () { }
> diff --git a/gcc/testsuite/rust/compile/torture/isolated_cr_line_comment.rs b/gcc/testsuite/rust/compile/torture/isolated_cr_line_comment.rs
> new file mode 100644
> index 00000000000..4e921a225c2
> --- /dev/null
> +++ b/gcc/testsuite/rust/compile/torture/isolated_cr_line_comment.rs
> @@ -0,0 +1,2 @@
> +// comment cr
> is allowed
> +pub fn main () { }
Hi Mark,
This patch looks good to me. When I tried to apply it to merge it I got
the following:
```
$ git am '[PATCH] Handle doc comment strings in lexer and parser.eml'
Applying: Handle doc comment strings in lexer and parser
error: corrupt patch at line 531
Patch failed at 0001 Handle doc comment strings in lexer and parser
hint: Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
```
Not sure if I have done something wrong, have you any pointers?
Thanks
--Phil
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 665 bytes --]
next prev parent reply other threads:[~2021-07-12 8:09 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-11 20:10 Mark Wielaard
2021-07-12 8:09 ` Philip Herron [this message]
2021-07-12 8:32 ` Mark Wielaard
2021-07-12 10:06 ` Philip Herron
2021-07-12 22:44 ` New contributor tasks Mark Wielaard
2021-07-13 13:16 ` Philip Herron
[not found] ` <CADYxmzTdEH2pHba1+1nq5AXEQAyb6UhT8xvRKdWB7bu41ex1UA@mail.gmail.com>
2021-07-17 14:25 ` Fwd: " The Other
2021-07-17 21:23 ` Mark Wielaard
2021-07-18 20:45 ` Mark Wielaard
2021-07-13 13:30 ` Thomas Schwinge
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=fa073e0b-5601-e0be-f022-96839e191c0c@embecosm.com \
--to=philip.herron@embecosm.com \
--cc=gcc-rust@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).