public inbox for gcc-rust@gcc.gnu.org
 help / color / mirror / Atom feed
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 --]

  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).