public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] parser: Add base for parsing const generic parameters
@ 2022-06-15 17:03 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-15 17:03 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:112d4212fc57a6387e971e6c9d84cbf05bf6d865

commit 112d4212fc57a6387e971e6c9d84cbf05bf6d865
Author: Arthur Cohen <arthur.cohen@embecosm.com>
Date:   Tue Jun 14 13:42:54 2022 +0200

    parser: Add base for parsing const generic parameters

Diff:
---
 gcc/rust/parse/rust-parse-impl.h               | 568 ++++++++++++++-----------
 gcc/testsuite/rust/compile/const_generics_1.rs |  19 +
 gcc/testsuite/rust/compile/const_generics_2.rs |   3 +
 3 files changed, 350 insertions(+), 240 deletions(-)

diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index ce68c16ac7c..ae6ef4a9595 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -2865,6 +2865,63 @@ Parser<ManagedTokenSource>::parse_generic_param (EndTokenPred is_end_token)
 			      std::move (outer_attrs)));
 	break;
       }
+      case CONST: {
+	lexer.skip_token ();
+
+	auto name = expect_token (IDENTIFIER);
+
+	if (!name || !expect_token (COLON))
+	  return nullptr;
+
+	auto type = parse_type ();
+	if (!type)
+	  return nullptr;
+
+	// FIXME: instantiate proper AST::ConstGeneric class here
+	// auto const_generic = new ...
+
+	// optional default value
+	if (lexer.peek_token ()->get_id () == EQUAL)
+	  {
+	    lexer.skip_token ();
+	    auto tok = lexer.peek_token ();
+
+	    switch (tok->get_id ())
+	      {
+		case LEFT_CURLY: {
+		  auto block = parse_block_expr ();
+		  // pass block to `const_generic`
+		  break;
+		}
+		case IDENTIFIER: {
+		  auto ident = tok->get_str ();
+		  // pass identifier to `const_generic`
+		  break;
+		}
+	      case MINUS:
+	      case STRING_LITERAL:
+	      case CHAR_LITERAL:
+	      case INT_LITERAL:
+	      case FLOAT_LITERAL:
+	      case TRUE_LITERAL:
+		case FALSE_LITERAL: {
+		  auto literal = parse_literal_expr ();
+		  // pass literal to `const_generic`
+		  break;
+		}
+	      default:
+		rust_error_at (tok->get_locus (),
+			       "invalid token for start of default value for "
+			       "const generic parameter: expected %<block%>, "
+			       "%<identifier%> or %<literal%>, got %qs",
+			       token_id_to_str (tok->get_id ()));
+	      }
+	  }
+
+	// param = std::unique_ptr<AST::GenericParam> (const_generic)
+
+	break;
+      }
     default:
       // FIXME: Can we clean this last call with a method call?
       rust_error_at (token->get_locus (),
@@ -2925,8 +2982,8 @@ Parser<ManagedTokenSource>::parse_generic_params (EndTokenPred is_end_token)
   return generic_params;
 }
 
-/* Parses lifetime generic parameters (pointers). Will also consume any trailing
- * comma. No extra checks for end token. */
+/* Parses lifetime generic parameters (pointers). Will also consume any
+ * trailing comma. No extra checks for end token. */
 template <typename ManagedTokenSource>
 std::vector<std::unique_ptr<AST::LifetimeParam>>
 Parser<ManagedTokenSource>::parse_lifetime_params ()
@@ -2958,8 +3015,8 @@ Parser<ManagedTokenSource>::parse_lifetime_params ()
   return lifetime_params;
 }
 
-/* Parses lifetime generic parameters (pointers). Will also consume any trailing
- * comma. Has extra is_end_token predicate checking. */
+/* Parses lifetime generic parameters (pointers). Will also consume any
+ * trailing comma. Has extra is_end_token predicate checking. */
 template <typename ManagedTokenSource>
 template <typename EndTokenPred>
 std::vector<std::unique_ptr<AST::LifetimeParam>>
@@ -2998,8 +3055,8 @@ Parser<ManagedTokenSource>::parse_lifetime_params (EndTokenPred is_end_token)
   return lifetime_params;
 }
 
-/* Parses lifetime generic parameters (objects). Will also consume any trailing
- * comma. No extra checks for end token.
+/* Parses lifetime generic parameters (objects). Will also consume any
+ * trailing comma. No extra checks for end token.
  * TODO: is this best solution? implements most of the same algorithm. */
 template <typename ManagedTokenSource>
 std::vector<AST::LifetimeParam>
@@ -3032,8 +3089,8 @@ Parser<ManagedTokenSource>::parse_lifetime_params_objs ()
   return lifetime_params;
 }
 
-/* Parses lifetime generic parameters (objects). Will also consume any trailing
- * comma. Has extra is_end_token predicate checking.
+/* Parses lifetime generic parameters (objects). Will also consume any
+ * trailing comma. Has extra is_end_token predicate checking.
  * TODO: is this best solution? implements most of the same algorithm. */
 template <typename ManagedTokenSource>
 template <typename EndTokenPred>
@@ -3092,7 +3149,8 @@ Parser<ManagedTokenSource>::parse_non_ptr_sequence (
 
       if (param.is_error ())
 	{
-	  // TODO: is it worth throwing away all params just because one failed?
+	  // TODO: is it worth throwing away all params just because one
+	  // failed?
 	  Error error (lexer.peek_token ()->get_locus (),
 		       std::move (error_msg));
 	  add_error (std::move (error));
@@ -3130,8 +3188,8 @@ Parser<ManagedTokenSource>::parse_lifetime_param ()
       return AST::LifetimeParam::create_error ();
     }
   lexer.skip_token ();
-  /* TODO: does this always create a named lifetime? or can a different type be
-   * made? */
+  /* TODO: does this always create a named lifetime? or can a different type
+   * be made? */
   AST::Lifetime lifetime (AST::Lifetime::NAMED, lifetime_tok->get_str (),
 			  lifetime_tok->get_locus ());
 
@@ -3212,12 +3270,12 @@ Parser<ManagedTokenSource>::parse_type_params (EndTokenPred is_end_token)
 
   type_params.shrink_to_fit ();
   return type_params;
-  /* TODO: this shares most code with parse_lifetime_params - good place to use
-   * template (i.e. parse_non_ptr_sequence if doable) */
+  /* TODO: this shares most code with parse_lifetime_params - good place to
+   * use template (i.e. parse_non_ptr_sequence if doable) */
 }
 
-/* Parses a single type (generic) parameter, not including commas. May change to
- * return value. */
+/* Parses a single type (generic) parameter, not including commas. May change
+ * to return value. */
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::TypeParam>
 Parser<ManagedTokenSource>::parse_type_param ()
@@ -3228,7 +3286,8 @@ Parser<ManagedTokenSource>::parse_type_param ()
   const_TokenPtr identifier_tok = lexer.peek_token ();
   if (identifier_tok->get_id () != IDENTIFIER)
     {
-      // return null as type param can't exist without this required identifier
+      // return null as type param can't exist without this required
+      // identifier
       return nullptr;
     }
   // TODO: create identifier from identifier token
@@ -3326,8 +3385,8 @@ Parser<ManagedTokenSource>::parse_function_params (EndTokenPred is_end_token)
   return params;
 }
 
-/* Parses a single regular (i.e. non-generic) parameter in a function or method,
- * i.e. the "name: type" bit. Also handles it not existing. */
+/* Parses a single regular (i.e. non-generic) parameter in a function or
+ * method, i.e. the "name: type" bit. Also handles it not existing. */
 template <typename ManagedTokenSource>
 AST::FunctionParam
 Parser<ManagedTokenSource>::parse_function_param ()
@@ -3380,8 +3439,8 @@ Parser<ManagedTokenSource>::parse_function_return_type ()
   return type;
 }
 
-/* Parses a "where clause" (in a function, struct, method, etc.). Also handles a
- * where clause not existing, in which it will return
+/* Parses a "where clause" (in a function, struct, method, etc.). Also handles
+ * a where clause not existing, in which it will return
  * WhereClause::create_empty(), which can be checked via
  * WhereClause::is_empty(). */
 template <typename ManagedTokenSource>
@@ -3397,8 +3456,8 @@ Parser<ManagedTokenSource>::parse_where_clause ()
 
   lexer.skip_token ();
 
-  /* parse where clause items - this is not a separate rule in the reference so
-   * won't be here */
+  /* parse where clause items - this is not a separate rule in the reference
+   * so won't be here */
   std::vector<std::unique_ptr<AST::WhereClauseItem>> where_clause_items;
 
   /* HACK: where clauses end with a right curly or semicolon or equals in all
@@ -3438,7 +3497,8 @@ template <typename ManagedTokenSource>
 std::unique_ptr<AST::WhereClauseItem>
 Parser<ManagedTokenSource>::parse_where_clause_item ()
 {
-  // shitty cheat way of determining lifetime or type bound - test for lifetime
+  // shitty cheat way of determining lifetime or type bound - test for
+  // lifetime
   const_TokenPtr t = lexer.peek_token ();
 
   if (t->get_id () == LIFETIME)
@@ -3509,7 +3569,8 @@ Parser<ManagedTokenSource>::parse_type_bound_where_clause_item ()
 				       std::move (type_param_bounds), locus));
 }
 
-// Parses a for lifetimes clause, including the for keyword and angle brackets.
+// Parses a for lifetimes clause, including the for keyword and angle
+// brackets.
 template <typename ManagedTokenSource>
 std::vector<AST::LifetimeParam>
 Parser<ManagedTokenSource>::parse_for_lifetimes ()
@@ -3637,7 +3698,8 @@ template <typename ManagedTokenSource>
 std::unique_ptr<AST::TypeParamBound>
 Parser<ManagedTokenSource>::parse_type_param_bound ()
 {
-  // shitty cheat way of determining lifetime or trait bound - test for lifetime
+  // shitty cheat way of determining lifetime or trait bound - test for
+  // lifetime
   const_TokenPtr t = lexer.peek_token ();
   switch (t->get_id ())
     {
@@ -3724,8 +3786,8 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds ()
 
       lifetime_bounds.push_back (std::move (lifetime));
 
-      /* plus is maybe not allowed at end - spec defines it weirdly, so assuming
-       * allowed at end */
+      /* plus is maybe not allowed at end - spec defines it weirdly, so
+       * assuming allowed at end */
       if (lexer.peek_token ()->get_id () != PLUS)
 	break;
 
@@ -3761,8 +3823,8 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds (EndTokenPred is_end_token)
 
       lifetime_bounds.push_back (std::move (lifetime));
 
-      /* plus is maybe not allowed at end - spec defines it weirdly, so assuming
-       * allowed at end */
+      /* plus is maybe not allowed at end - spec defines it weirdly, so
+       * assuming allowed at end */
       if (lexer.peek_token ()->get_id () != PLUS)
 	break;
 
@@ -3860,9 +3922,9 @@ std::unique_ptr<AST::Struct>
 Parser<ManagedTokenSource>::parse_struct (AST::Visibility vis,
 					  AST::AttrVec outer_attrs)
 {
-  /* TODO: determine best way to parse the proper struct vs tuple struct - share
-   * most of initial constructs so lookahead might be impossible, and if not
-   * probably too expensive. Best way is probably unified parsing for the
+  /* TODO: determine best way to parse the proper struct vs tuple struct -
+   * share most of initial constructs so lookahead might be impossible, and if
+   * not probably too expensive. Best way is probably unified parsing for the
    * initial parts and then pass them in as params to more derived functions.
    * Alternatively, just parse everything in this one function - do this if
    * function not too long. */
@@ -3930,8 +3992,8 @@ Parser<ManagedTokenSource>::parse_struct (AST::Visibility vis,
 			      std::move (outer_attrs), locus));
     }
 
-  // assume it is a proper struct being parsed and continue outside of switch -
-  // label only here to suppress warning
+  // assume it is a proper struct being parsed and continue outside of switch
+  // - label only here to suppress warning
 
   // parse where clause, which is optional
   AST::WhereClause where_clause = parse_where_clause ();
@@ -4059,7 +4121,8 @@ Parser<ManagedTokenSource>::parse_struct_fields (EndTokenPred is_end_tok)
   // TODO: template if possible (parse_non_ptr_seq)
 }
 
-// Parses a single struct field (in a struct definition). Does not parse commas.
+// Parses a single struct field (in a struct definition). Does not parse
+// commas.
 template <typename ManagedTokenSource>
 AST::StructField
 Parser<ManagedTokenSource>::parse_struct_field ()
@@ -4124,8 +4187,8 @@ Parser<ManagedTokenSource>::parse_tuple_fields ()
 
   // maybe think of a better control structure here - do-while with an initial
   // error state? basically, loop through field list until can't find any more
-  // params HACK: all current syntax uses of tuple fields have them ending with
-  // a right paren token
+  // params HACK: all current syntax uses of tuple fields have them ending
+  // with a right paren token
   const_TokenPtr t = lexer.peek_token ();
   while (t->get_id () == COMMA)
     {
@@ -4156,7 +4219,8 @@ Parser<ManagedTokenSource>::parse_tuple_fields ()
   fields.shrink_to_fit ();
   return fields;
 
-  // TODO: this shares basically all code with function params and struct fields
+  // TODO: this shares basically all code with function params and struct
+  // fields
   // - templates?
 }
 
@@ -4434,8 +4498,8 @@ Parser<ManagedTokenSource>::parse_union (AST::Visibility vis,
       return nullptr;
     }
 
-  /* parse union inner items as "struct fields" because hey, syntax reuse. Spec
-   * said so. */
+  /* parse union inner items as "struct fields" because hey, syntax reuse.
+   * Spec said so. */
   std::vector<AST::StructField> union_fields
     = parse_struct_fields ([] (TokenId id) { return id == RIGHT_CURLY; });
 
@@ -4451,8 +4515,8 @@ Parser<ManagedTokenSource>::parse_union (AST::Visibility vis,
 		    std::move (union_fields), std::move (outer_attrs), locus));
 }
 
-/* Parses a "constant item" (compile-time constant to maybe "inline" throughout
- * the program - like constexpr). */
+/* Parses a "constant item" (compile-time constant to maybe "inline"
+ * throughout the program - like constexpr). */
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::ConstantItem>
 Parser<ManagedTokenSource>::parse_const_item (AST::Visibility vis,
@@ -4710,18 +4774,18 @@ Parser<ManagedTokenSource>::parse_trait_item ()
 	    return nullptr;
 	  }
 
-	/* now for function vs method disambiguation - method has opening "self"
-	 * param */
+	/* now for function vs method disambiguation - method has opening
+	 * "self" param */
 	AST::SelfParam self_param = parse_self_param ();
-	/* FIXME: ensure that self param doesn't accidently consume tokens for a
-	 * function */
+	/* FIXME: ensure that self param doesn't accidently consume tokens for
+	 * a function */
 	bool is_method = false;
 	if (!self_param.is_error ())
 	  {
 	    is_method = true;
 
-	    /* skip comma so function and method regular params can be parsed in
-	     * same way */
+	    /* skip comma so function and method regular params can be parsed
+	     * in same way */
 	    if (lexer.peek_token ()->get_id () == COMMA)
 	      lexer.skip_token ();
 	  }
@@ -4815,8 +4879,8 @@ Parser<ManagedTokenSource>::parse_trait_item ()
 	  {
 	    return macro_invoc;
 	  }
-	/* FIXME: macro invocations can only start with certain tokens. be more
-	 * picky with these? */
+	/* FIXME: macro invocations can only start with certain tokens. be
+	 * more picky with these? */
       }
     }
 }
@@ -4905,16 +4969,16 @@ Parser<ManagedTokenSource>::parse_trait_const (AST::AttrVec outer_attrs)
 			     locus));
 }
 
-/* Parses a struct "impl" item (both inherent impl and trait impl can be parsed
- * here), */
+/* Parses a struct "impl" item (both inherent impl and trait impl can be
+ * parsed here), */
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::Impl>
 Parser<ManagedTokenSource>::parse_impl (AST::Visibility vis,
 					AST::AttrVec outer_attrs)
 {
-  /* Note that only trait impls are allowed to be unsafe. So if unsafe, it must
-   * be a trait impl. However, this isn't enough for full disambiguation, so
-   * don't branch here. */
+  /* Note that only trait impls are allowed to be unsafe. So if unsafe, it
+   * must be a trait impl. However, this isn't enough for full disambiguation,
+   * so don't branch here. */
   Location locus = lexer.peek_token ()->get_locus ();
   bool is_unsafe = false;
   if (lexer.peek_token ()->get_id () == UNSAFE)
@@ -5218,8 +5282,8 @@ Parser<ManagedTokenSource>::parse_inherent_impl_item ()
 }
 
 /* For internal use only by parse_inherent_impl_item() - splits giant method
- * into smaller ones and prevents duplication of logic. Strictly, this parses a
- * function or method item inside an inherent impl item block. */
+ * into smaller ones and prevents duplication of logic. Strictly, this parses
+ * a function or method item inside an inherent impl item block. */
 // TODO: make this a templated function with "return type" as type param -
 // InherentImplItem is this specialisation of the template while TraitImplItem
 // will be the other.
@@ -5251,18 +5315,19 @@ Parser<ManagedTokenSource>::parse_inherent_impl_function_or_method (
       return nullptr;
     }
 
-  // now for function vs method disambiguation - method has opening "self" param
+  // now for function vs method disambiguation - method has opening "self"
+  // param
   AST::SelfParam self_param = parse_self_param ();
   /* FIXME: ensure that self param doesn't accidently consume tokens for a
-   * function one idea is to lookahead up to 4 tokens to see whether self is one
-   * of them */
+   * function one idea is to lookahead up to 4 tokens to see whether self is
+   * one of them */
   bool is_method = false;
   if (!self_param.is_error ())
     {
       is_method = true;
 
-      /* skip comma so function and method regular params can be parsed in same
-       * way */
+      /* skip comma so function and method regular params can be parsed in
+       * same way */
       if (lexer.peek_token ()->get_id () == COMMA)
 	lexer.skip_token ();
     }
@@ -5286,10 +5351,10 @@ Parser<ManagedTokenSource>::parse_inherent_impl_function_or_method (
   // parse function definition (in block) - semicolon not allowed
   if (lexer.peek_token ()->get_id () == SEMICOLON)
     {
-      Error error (
-	lexer.peek_token ()->get_locus (),
-	"%s declaration in inherent impl not allowed - must have a definition",
-	is_method ? "method" : "function");
+      Error error (lexer.peek_token ()->get_locus (),
+		   "%s declaration in inherent impl not allowed - must have "
+		   "a definition",
+		   is_method ? "method" : "function");
       add_error (std::move (error));
 
       lexer.skip_token ();
@@ -5347,7 +5412,8 @@ Parser<ManagedTokenSource>::parse_trait_impl_item ()
     case SELF:
     case CRATE:
     case DOLLAR_SIGN:
-      // these seem to be SimplePath tokens, so this is a macro invocation semi
+      // these seem to be SimplePath tokens, so this is a macro invocation
+      // semi
       return parse_macro_invocation_semi (std::move (outer_attrs));
     case TYPE:
       return parse_type_alias (AST::Visibility::create_private (),
@@ -5454,7 +5520,8 @@ std::unique_ptr<AST::TraitImplItem>
 Parser<ManagedTokenSource>::parse_trait_impl_function_or_method (
   AST::Visibility vis, AST::AttrVec outer_attrs)
 {
-  // this shares virtually all logic with parse_inherent_impl_function_or_method
+  // this shares virtually all logic with
+  // parse_inherent_impl_function_or_method
   // - template?
   Location locus = lexer.peek_token ()->get_locus ();
 
@@ -5489,7 +5556,8 @@ Parser<ManagedTokenSource>::parse_trait_impl_function_or_method (
       return nullptr;
     }
 
-  // now for function vs method disambiguation - method has opening "self" param
+  // now for function vs method disambiguation - method has opening "self"
+  // param
   AST::SelfParam self_param = parse_self_param ();
   // FIXME: ensure that self param doesn't accidently consume tokens for a
   // function
@@ -5498,8 +5566,8 @@ Parser<ManagedTokenSource>::parse_trait_impl_function_or_method (
     {
       is_method = true;
 
-      // skip comma so function and method regular params can be parsed in same
-      // way
+      // skip comma so function and method regular params can be parsed in
+      // same way
       if (lexer.peek_token ()->get_id () == COMMA)
 	{
 	  lexer.skip_token ();
@@ -5921,8 +5989,8 @@ Parser<ManagedTokenSource>::parse_stmt (ParseRestrictions restrictions)
 
   // parsing this will be annoying because of the many different possibilities
   /* best may be just to copy paste in parse_item switch, and failing that try
-   * to parse outer attributes, and then pass them in to either a let statement
-   * or (fallback) expression statement. */
+   * to parse outer attributes, and then pass them in to either a let
+   * statement or (fallback) expression statement. */
   // FIXME: think of a way to do this without such a large switch?
   t = lexer.peek_token ();
   switch (t->get_id ())
@@ -5976,8 +6044,8 @@ Parser<ManagedTokenSource>::parse_stmt (ParseRestrictions restrictions)
 	       || lexer.peek_token (1)->get_id () == EXCLAM)
 	{
 	  // FIXME: ensure doesn't take any expressions by mistake
-	  /* path (probably) or macro invocation, so probably a macro invocation
-	   * semi */
+	  /* path (probably) or macro invocation, so probably a macro
+	   * invocation semi */
 	  return parse_macro_item (std::move (outer_attrs));
 	}
       gcc_fallthrough ();
@@ -6262,8 +6330,8 @@ Parser<ManagedTokenSource>::parse_generic_args_binding ()
 }
 
 /* Parses a single type path segment (not including opening scope resolution,
- * but includes any internal ones). Includes generic args or type path functions
- * too. */
+ * but includes any internal ones). Includes generic args or type path
+ * functions too. */
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::TypePathSegment>
 Parser<ManagedTokenSource>::parse_type_path_segment ()
@@ -6460,8 +6528,8 @@ Parser<ManagedTokenSource>::parse_path_expr_segment ()
     }
 
   // parse generic args (and turbofish), if they exist
-  /* use lookahead to determine if they actually exist (don't want to accidently
-   * parse over next ident segment) */
+  /* use lookahead to determine if they actually exist (don't want to
+   * accidently parse over next ident segment) */
   if (lexer.peek_token ()->get_id () == SCOPE_RESOLUTION
       && lexer.peek_token (1)->get_id () == LEFT_ANGLE)
     {
@@ -6478,8 +6546,8 @@ Parser<ManagedTokenSource>::parse_path_expr_segment ()
   return AST::PathExprSegment (std::move (ident), locus);
 }
 
-/* Parses a fully qualified path in expression (i.e. a pattern). FIXME does not
- * parse outer attrs. */
+/* Parses a fully qualified path in expression (i.e. a pattern). FIXME does
+ * not parse outer attrs. */
 template <typename ManagedTokenSource>
 AST::QualifiedPathInExpression
 Parser<ManagedTokenSource>::parse_qualified_path_in_expression (
@@ -6487,14 +6555,14 @@ Parser<ManagedTokenSource>::parse_qualified_path_in_expression (
 {
   /* Note: the Rust grammar is defined in such a way that it is impossible to
    * determine whether a prospective qualified path is a
-   * QualifiedPathInExpression or QualifiedPathInType in all cases by the rules
-   * themselves (the only possible difference is a TypePathSegment with
-   * function, and lookahead to find this is too difficult). However, as this is
-   * a pattern and QualifiedPathInType is a type, I believe it that their
+   * QualifiedPathInExpression or QualifiedPathInType in all cases by the
+   * rules themselves (the only possible difference is a TypePathSegment with
+   * function, and lookahead to find this is too difficult). However, as this
+   * is a pattern and QualifiedPathInType is a type, I believe it that their
    * construction will not be confused (due to rules regarding patterns vs
    * types).
-   * As such, this function will not attempt to minimise errors created by their
-   * confusion. */
+   * As such, this function will not attempt to minimise errors created by
+   * their confusion. */
 
   // parse the qualified path type (required)
   AST::QualifiedPathType qual_path_type
@@ -6568,8 +6636,8 @@ Parser<ManagedTokenSource>::parse_qualified_path_type (
   Location pratt_parsed_loc)
 {
   Location locus = pratt_parsed_loc;
-  /* TODO: should this actually be error? is there anywhere where this could be
-   * valid? */
+  /* TODO: should this actually be error? is there anywhere where this could
+   * be valid? */
   if (locus == Linemap::unknown_location ())
     {
       locus = lexer.peek_token ()->get_locus ();
@@ -6612,8 +6680,8 @@ Parser<ManagedTokenSource>::parse_qualified_path_type (
 	}
     }
 
-  /* NOTE: should actually be a right-angle token, so skip_generics_right_angle
-   * shouldn't be required */
+  /* NOTE: should actually be a right-angle token, so
+   * skip_generics_right_angle shouldn't be required */
   if (!skip_token (RIGHT_ANGLE))
     {
       // skip after somewhere?
@@ -6845,9 +6913,9 @@ Parser<ManagedTokenSource>::parse_method ()
 
   if (!skip_token (RIGHT_PAREN))
     {
-      Error error (
-	lexer.peek_token ()->get_locus (),
-	"method declaration missing closing parentheses after parameter list");
+      Error error (lexer.peek_token ()->get_locus (),
+		   "method declaration missing closing parentheses after "
+		   "parameter list");
       add_error (std::move (error));
 
       skip_after_next_block ();
@@ -6887,15 +6955,17 @@ std::unique_ptr<AST::ExprStmt>
 Parser<ManagedTokenSource>::parse_expr_stmt (AST::AttrVec outer_attrs,
 					     ParseRestrictions restrictions)
 {
-  /* potential thoughts - define new virtual method "has_block()" on expr. parse
-   * expr and then determine whether semicolon is needed as a result of this
-   * method. but then this would require dynamic_cast, which is not allowed. */
+  /* potential thoughts - define new virtual method "has_block()" on expr.
+   * parse expr and then determine whether semicolon is needed as a result of
+   * this method. but then this would require dynamic_cast, which is not
+   * allowed. */
 
   /* okay new thought - big switch to disambiguate exprs with blocks - either
-   * block expr, async block expr, unsafe block expr, loop expr, if expr, if let
-   * expr, or match expr. So all others are exprs without block. */
-  /* new thought: possible initial tokens: 'loop', 'while', 'for', lifetime (and
-   * then ':' and then loop), 'if', 'match', '{', 'async', 'unsafe' (and then
+   * block expr, async block expr, unsafe block expr, loop expr, if expr, if
+   * let expr, or match expr. So all others are exprs without block. */
+  /* new thought: possible initial tokens: 'loop', 'while', 'for', lifetime
+   * (and then ':' and then loop), 'if', 'match', '{', 'async', 'unsafe' (and
+   * then
    * '{')). This seems to have no ambiguity. */
 
   const_TokenPtr t = lexer.peek_token ();
@@ -6929,8 +6999,8 @@ Parser<ManagedTokenSource>::parse_expr_stmt (AST::AttrVec outer_attrs,
 	  }
       }
       case UNSAFE: {
-	/* FIXME: are there any expressions without blocks that can have unsafe
-	 * as their first token? Or is unsafe the only one? */
+	/* FIXME: are there any expressions without blocks that can have
+	 * unsafe as their first token? Or is unsafe the only one? */
 	// safe side for now
 	if (lexer.peek_token (1)->get_id () == LEFT_CURLY)
 	  {
@@ -6944,9 +7014,9 @@ Parser<ManagedTokenSource>::parse_expr_stmt (AST::AttrVec outer_attrs,
       }
     default:
       // not a parse expr with block, so must be expr without block
-      /* TODO: if possible, be more selective about possible expr without block
-       * initial tokens in order to prevent more syntactical errors at parse
-       * time. */
+      /* TODO: if possible, be more selective about possible expr without
+       * block initial tokens in order to prevent more syntactical errors at
+       * parse time. */
       return parse_expr_stmt_without_block (std::move (outer_attrs),
 					    restrictions);
     }
@@ -7066,8 +7136,8 @@ std::unique_ptr<AST::ExprStmtWithoutBlock>
 Parser<ManagedTokenSource>::parse_expr_stmt_without_block (
   AST::AttrVec outer_attrs, ParseRestrictions restrictions)
 {
-  /* TODO: maybe move more logic for expr without block in here for better error
-   * handling */
+  /* TODO: maybe move more logic for expr without block in here for better
+   * error handling */
 
   // attempt to parse via parse_expr_without_block - seems to work
   std::unique_ptr<AST::ExprWithoutBlock> expr = nullptr;
@@ -7118,30 +7188,32 @@ Parser<ManagedTokenSource>::parse_expr_without_block (
    *  - await expr            expr '.' 'await'
    *  - (array/slice) index expr  expr '[' expr ']'
    *  - tuple expr            '(' inner_attributes tuple_elems? ')'
-   *      note that a single elem tuple is distinguished from a grouped expr by
-   * a trailing comma, i.e. a grouped expr is preferred over a tuple expr
+   *      note that a single elem tuple is distinguished from a grouped expr
+   * by a trailing comma, i.e. a grouped expr is preferred over a tuple expr
    *  - tuple index expr      expr '.' tuple_index
    *  - struct expr           path_in_expr (and optional other stuff)
    *  - enum variant expr     path_in_expr (and optional other stuff)
    *      this means that there is no syntactic difference between an enum
    * variant and a struct
-   *      - only name resolution can tell the difference. Thus, maybe rework AST
-   * to take this into account ("struct or enum" nodes?)
+   *      - only name resolution can tell the difference. Thus, maybe rework
+   * AST to take this into account ("struct or enum" nodes?)
    *  - (function) call expr  expr '(' call_params? ')'
    *  - method call expr      expr '.' path_expr_segment '(' call_params? ')'
    *  - field expr            expr '.' identifier
    *      note that method call expr is preferred, i.e. field expr must not be
    * followed by parenthesised expression sequence.
-   *  - closure expr          'move'? ( '||' | '|' closure_params? '|' ) ( expr
-   * | '->' type_no_bounds block_expr )
+   *  - closure expr          'move'? ( '||' | '|' closure_params? '|' ) (
+   * expr | '->' type_no_bounds block_expr )
    *  - continue expr         'continue' labelled_lifetime?
    *  - break expr            'break' labelled_lifetime? expr?
-   *  - range expr            many different types but all involve '..' or '..='
+   *  - range expr            many different types but all involve '..' or
+   * '..='
    *  - return expr           'return' as 1st tok
    *  - macro invocation      identifier then :: or identifier then !
    * (simple_path '!')
    *
-   * any that have rules beginning with 'expr' should probably be pratt-parsed,
+   * any that have rules beginning with 'expr' should probably be
+   * pratt-parsed,
    * with parsing type to use determined by token AND lookahead. */
 
   // ok well at least can do easy ones
@@ -7164,8 +7236,10 @@ Parser<ManagedTokenSource>::parse_expr_without_block (
       // array expr (creation, not index)
       return parse_array_expr (std::move (outer_attrs));
     case LEFT_PAREN:
-      /* either grouped expr or tuple expr - depends on whether there is a comma
-       * inside the parentheses - if so, tuple expr, otherwise, grouped expr. */
+      /* either grouped expr or tuple expr - depends on whether there is a
+       * comma
+       * inside the parentheses - if so, tuple expr, otherwise, grouped expr.
+       */
       return parse_grouped_or_tuple_expr (std::move (outer_attrs));
       default: {
 	/* HACK: piggyback on pratt parsed expr and abuse polymorphism to
@@ -8179,8 +8253,8 @@ Parser<ManagedTokenSource>::parse_for_loop_expr (AST::AttrVec outer_attrs,
       return nullptr;
     }
 
-  /* parse iterator expression, which is required - also HACK to prevent struct
-   * expr */
+  /* parse iterator expression, which is required - also HACK to prevent
+   * struct expr */
   ParseRestrictions no_struct_expr;
   no_struct_expr.can_be_struct_expr = false;
   std::unique_ptr<AST::Expr> expr = parse_expr ({}, no_struct_expr);
@@ -8219,8 +8293,8 @@ std::unique_ptr<AST::BaseLoopExpr>
 Parser<ManagedTokenSource>::parse_labelled_loop_expr (AST::AttrVec outer_attrs)
 {
   /* TODO: decide whether it should not work if there is no label, or parse it
-   * with no label at the moment, I will make it not work with no label because
-   * that's the implication. */
+   * with no label at the moment, I will make it not work with no label
+   * because that's the implication. */
 
   if (lexer.peek_token ()->get_id () != LIFETIME)
     {
@@ -8304,8 +8378,8 @@ Parser<ManagedTokenSource>::parse_match_expr (AST::AttrVec outer_attrs,
       // skip somewhere?
       return nullptr;
     }
-  /* TODO: check for scrutinee expr not being struct expr? or do so in semantic
-   * analysis */
+  /* TODO: check for scrutinee expr not being struct expr? or do so in
+   * semantic analysis */
 
   if (!skip_token (LEFT_CURLY))
     {
@@ -8483,9 +8557,9 @@ Parser<ManagedTokenSource>::parse_match_arm ()
 			std::move (guard_expr), std::move (outer_attrs));
 }
 
-/* Parses the patterns used in a match arm. End token id is the id of the token
- * that would exist after the patterns are done (e.g. '}' for match expr, '='
- * for if let and while let). */
+/* Parses the patterns used in a match arm. End token id is the id of the
+ * token that would exist after the patterns are done (e.g. '}' for match
+ * expr, '=' for if let and while let). */
 template <typename ManagedTokenSource>
 std::vector<std::unique_ptr<AST::Pattern>>
 Parser<ManagedTokenSource>::parse_match_arm_patterns (TokenId end_token_id)
@@ -8494,8 +8568,8 @@ Parser<ManagedTokenSource>::parse_match_arm_patterns (TokenId end_token_id)
   if (lexer.peek_token ()->get_id () == PIPE)
     lexer.skip_token ();
   /* TODO: do I even need to store the result of this? can't be used.
-   * If semantically different, I need a wrapped "match arm patterns" object for
-   * this. */
+   * If semantically different, I need a wrapped "match arm patterns" object
+   * for this. */
 
   std::vector<std::unique_ptr<AST::Pattern>> patterns;
 
@@ -8925,14 +8999,16 @@ Parser<ManagedTokenSource>::parse_type ()
    *  TraitBound              '?'? ForLifetimes? TypePath | '(' '?'?
    * ForLifetimes? TypePath ')' BareFunctionType:        ForLifetimes?
    * FunctionQualifiers 'fn' etc. ForLifetimes (not type) 'for' '<'
-   * LifetimeParams '>' FunctionQualifiers      ( 'async' | 'const' )? 'unsafe'?
-   * ('extern' abi?)? QualifiedPathInType:     '<' Type ( 'as' TypePath )? '>' (
+   * LifetimeParams '>' FunctionQualifiers      ( 'async' | 'const' )?
+   * 'unsafe'?
+   * ('extern' abi?)? QualifiedPathInType:     '<' Type ( 'as' TypePath )? '>'
+   * (
    * '::' TypePathSegment )+ TypePath:                '::'? TypePathSegment (
    * '::' TypePathSegment)* ArrayType:               '[' Type ';' Expr ']'
    * ReferenceType:           '&' Lifetime? 'mut'? TypeNoBounds
    * RawPointerType:          '*' ( 'mut' | 'const' ) TypeNoBounds
-   * TupleType:               '(' Type etc. - regular tuple stuff. Also regular
-   * tuple vs parenthesised precedence
+   * TupleType:               '(' Type etc. - regular tuple stuff. Also
+   * regular tuple vs parenthesised precedence
    *
    * Disambiguate between macro and type path via type path being parsed, and
    * then if '!' found, convert type path to simple path for macro. Usual
@@ -8999,10 +9075,10 @@ Parser<ManagedTokenSource>::parse_type ()
 	/* for parsing path component of each rule, perhaps parse it as a
 	 * typepath and attempt conversion to simplepath if a trailing '!' is
 	 * found */
-	/* Type path also includes TraitObjectTypeOneBound BUT if it starts with
-	 * it, it is exactly the same as a TypePath syntactically, so this is a
-	 * syntactical ambiguity. As such, the parser will parse it as a
-	 * TypePath. This, however, does not prevent TraitObjectType from
+	/* Type path also includes TraitObjectTypeOneBound BUT if it starts
+	 * with it, it is exactly the same as a TypePath syntactically, so
+	 * this is a syntactical ambiguity. As such, the parser will parse it
+	 * as a TypePath. This, however, does not prevent TraitObjectType from
 	 * starting with a typepath. */
 
 	// parse path as type path
@@ -9082,9 +9158,9 @@ Parser<ManagedTokenSource>::parse_type ()
 	  }
       }
     case LEFT_PAREN:
-      /* tuple type or parenthesised type - requires further disambiguation (the
-       * usual). ok apparently can be a parenthesised TraitBound too, so could
-       * be TraitObjectTypeOneBound or TraitObjectType */
+      /* tuple type or parenthesised type - requires further disambiguation
+       * (the usual). ok apparently can be a parenthesised TraitBound too, so
+       * could be TraitObjectTypeOneBound or TraitObjectType */
       return parse_paren_prefixed_type ();
     case FOR:
       // TraitObjectTypeOneBound or BareFunctionType
@@ -9245,15 +9321,15 @@ Parser<ManagedTokenSource>::parse_type ()
 }
 
 /* Parses a type that has '(' as its first character. Returns a tuple type,
- * parenthesised type, TraitObjectTypeOneBound, or TraitObjectType depending on
- * following characters. */
+ * parenthesised type, TraitObjectTypeOneBound, or TraitObjectType depending
+ * on following characters. */
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::Type>
 Parser<ManagedTokenSource>::parse_paren_prefixed_type ()
 {
-  /* NOTE: Syntactical ambiguity of a parenthesised trait bound is considered a
-   * trait bound, not a parenthesised type, so that it can still be used in type
-   * param bounds. */
+  /* NOTE: Syntactical ambiguity of a parenthesised trait bound is considered
+   * a trait bound, not a parenthesised type, so that it can still be used in
+   * type param bounds. */
 
   /* NOTE: this implementation is really shit but I couldn't think of a better
    * one. It requires essentially breaking polymorphism and downcasting via
@@ -9379,12 +9455,12 @@ Parser<ManagedTokenSource>::parse_paren_prefixed_type ()
       return std::unique_ptr<AST::TupleType> (
 	new AST::TupleType (std::move (types), left_delim_locus));
     }
-  /* TODO: ensure that this ensures that dynamic dispatch for traits is not lost
-   * somehow */
+  /* TODO: ensure that this ensures that dynamic dispatch for traits is not
+   * lost somehow */
 }
 
-/* Parses a type that has 'for' as its first character. This means it has a "for
- * lifetimes", so returns either a BareFunctionType, TraitObjectType, or
+/* Parses a type that has 'for' as its first character. This means it has a
+ * "for lifetimes", so returns either a BareFunctionType, TraitObjectType, or
  * TraitObjectTypeOneBound depending on following characters. */
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::Type>
@@ -9703,8 +9779,8 @@ Parser<ManagedTokenSource>::parse_raw_pointer_type ()
     new AST::RawPointerType (kind, std::move (type), locus));
 }
 
-/* Parses a slice or array type, depending on following arguments (as lookahead
- * is not possible). */
+/* Parses a slice or array type, depending on following arguments (as
+ * lookahead is not possible). */
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::TypeNoBounds>
 Parser<ManagedTokenSource>::parse_slice_or_array_type ()
@@ -9828,10 +9904,10 @@ Parser<ManagedTokenSource>::parse_type_no_bounds ()
 	/* for parsing path component of each rule, perhaps parse it as a
 	 * typepath and attempt conversion to simplepath if a trailing '!' is
 	 * found */
-	/* Type path also includes TraitObjectTypeOneBound BUT if it starts with
-	 * it, it is exactly the same as a TypePath syntactically, so this is a
-	 * syntactical ambiguity. As such, the parser will parse it as a
-	 * TypePath. This, however, does not prevent TraitObjectType from
+	/* Type path also includes TraitObjectTypeOneBound BUT if it starts
+	 * with it, it is exactly the same as a TypePath syntactically, so
+	 * this is a syntactical ambiguity. As such, the parser will parse it
+	 * as a TypePath. This, however, does not prevent TraitObjectType from
 	 * starting with a typepath. */
 
 	// parse path as type path
@@ -9882,9 +9958,9 @@ Parser<ManagedTokenSource>::parse_type_no_bounds ()
 	  }
       }
     case LEFT_PAREN:
-      /* tuple type or parenthesised type - requires further disambiguation (the
-       * usual). ok apparently can be a parenthesised TraitBound too, so could
-       * be TraitObjectTypeOneBound */
+      /* tuple type or parenthesised type - requires further disambiguation
+       * (the usual). ok apparently can be a parenthesised TraitBound too, so
+       * could be TraitObjectTypeOneBound */
       return parse_paren_prefixed_type_no_bounds ();
     case FOR:
     case ASYNC:
@@ -9954,8 +10030,8 @@ Parser<ManagedTokenSource>::parse_type_no_bounds ()
 
 	if (lexer.peek_token ()->get_id () == LIFETIME)
 	  {
-	    /* means that cannot be TraitObjectTypeOneBound - so here for error
-	     * message */
+	    /* means that cannot be TraitObjectTypeOneBound - so here for
+	     * error message */
 	    Error error (lexer.peek_token ()->get_locus (),
 			 "lifetime as bound in TraitObjectTypeOneBound "
 			 "is not allowed, so cannot be TypeNoBounds");
@@ -10015,8 +10091,8 @@ Parser<ManagedTokenSource>::parse_paren_prefixed_type_no_bounds ()
    * parse_paren_prefixed_type, but I was lazy. So FIXME for future.*/
 
   /* NOTE: again, syntactical ambiguity of a parenthesised trait bound is
-   * considered a trait bound, not a parenthesised type, so that it can still be
-   * used in type param bounds. */
+   * considered a trait bound, not a parenthesised type, so that it can still
+   * be used in type param bounds. */
 
   Location left_paren_locus = lexer.peek_token ()->get_locus ();
 
@@ -10105,8 +10181,8 @@ Parser<ManagedTokenSource>::parse_paren_prefixed_type_no_bounds ()
       return std::unique_ptr<AST::TupleType> (
 	new AST::TupleType (std::move (types), left_paren_locus));
     }
-  /* TODO: ensure that this ensures that dynamic dispatch for traits is not lost
-   * somehow */
+  /* TODO: ensure that this ensures that dynamic dispatch for traits is not
+   * lost somehow */
 }
 
 /* Parses a literal pattern or range pattern. Assumes that literals passed in
@@ -10353,7 +10429,8 @@ Parser<ManagedTokenSource>::parse_pattern ()
       return std::unique_ptr<AST::LiteralPattern> (
 	new AST::LiteralPattern (t->get_str (), AST::Literal::BYTE_STRING,
 				 t->get_locus ()));
-    // raw string and raw byte string literals too if they are readded to lexer
+    // raw string and raw byte string literals too if they are readded to
+    // lexer
     case MINUS:
       if (lexer.peek_token (1)->get_id () == INT_LITERAL)
 	{
@@ -10379,9 +10456,10 @@ Parser<ManagedTokenSource>::parse_pattern ()
     case MUT:
       return parse_identifier_pattern ();
     case IDENTIFIER:
-      /* if identifier with no scope resolution afterwards, identifier pattern.
-       * if scope resolution afterwards, path pattern (or range pattern or
-       * struct pattern or tuple struct pattern) or macro invocation */
+      /* if identifier with no scope resolution afterwards, identifier
+       * pattern. if scope resolution afterwards, path pattern (or range
+       * pattern or struct pattern or tuple struct pattern) or macro
+       * invocation */
       return parse_ident_leading_pattern ();
     case AMP:
     case LOGICAL_AND:
@@ -10568,8 +10646,8 @@ Parser<ManagedTokenSource>::parse_reference_pattern ()
 			       t->get_locus ()));
 }
 
-/* Parses a grouped pattern or tuple pattern. Prefers grouped over tuple if only
- * a single element with no commas. */
+/* Parses a grouped pattern or tuple pattern. Prefers grouped over tuple if
+ * only a single element with no commas. */
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::Pattern>
 Parser<ManagedTokenSource>::parse_grouped_or_tuple_pattern ()
@@ -11357,7 +11435,8 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr_with_block (
   if (tok->get_id () == RIGHT_CURLY)
     return ExprOrStmt (std::move (expr));
 
-  // internal block expr must either have semicolons followed, or evaluate to ()
+  // internal block expr must either have semicolons followed, or evaluate to
+  // ()
   auto locus = expr->get_locus ();
   std::unique_ptr<AST::ExprStmtWithBlock> stmt (
     new AST::ExprStmtWithBlock (std::move (expr), locus,
@@ -11390,16 +11469,16 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr_without_block ()
 
   // parsing this will be annoying because of the many different possibilities
   /* best may be just to copy paste in parse_item switch, and failing that try
-   * to parse outer attributes, and then pass them in to either a let statement
-   * or (fallback) expression statement. */
+   * to parse outer attributes, and then pass them in to either a let
+   * statement or (fallback) expression statement. */
   // FIXME: think of a way to do this without such a large switch?
 
   /* FIXME: for expressions at least, the only way that they can really be
    * parsed properly in this way is if they don't support operators on them.
    * They must be pratt-parsed otherwise. As such due to composability, only
    * explicit statements will have special cases here. This should roughly
-   * correspond to "expr-with-block", but this warning is here in case it isn't
-   * the case. */
+   * correspond to "expr-with-block", but this warning is here in case it
+   * isn't the case. */
   t = lexer.peek_token ();
   switch (t->get_id ())
     {
@@ -11495,8 +11574,8 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr_without_block ()
       }
       /* FIXME: this is either a macro invocation or macro invocation semi.
        * start parsing to determine which one it is. */
-      // FIXME: or this is another path-based thing - struct/enum or path itself
-      // return parse_path_based_stmt_or_expr(std::move(outer_attrs));
+      // FIXME: or this is another path-based thing - struct/enum or path
+      // itself return parse_path_based_stmt_or_expr(std::move(outer_attrs));
       // FIXME: old code there
     case LOOP:
     case WHILE:
@@ -11560,9 +11639,9 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr_without_block ()
 	       || lexer.peek_token (1)->get_id () == EXCLAM
 	       || lexer.peek_token (1)->get_id () == LEFT_CURLY)
 	{
-	  /* path (probably) or macro invocation or struct or enum, so probably
-	   * a macro invocation semi decide how to parse - probably parse path
-	   * and then get macro from it */
+	  /* path (probably) or macro invocation or struct or enum, so
+	   * probably a macro invocation semi decide how to parse - probably
+	   * parse path and then get macro from it */
 
 	  // FIXME: old code was good until composability was required
 	  // return parse_path_based_stmt_or_expr(std::move(outer_attrs));
@@ -11625,8 +11704,8 @@ Parser<ManagedTokenSource>::parse_path_based_stmt_or_expr (
   switch (t2->get_id ())
     {
       case EXCLAM: {
-	/* macro invocation or macro invocation semi - depends on whether there
-	 * is a final ';' */
+	/* macro invocation or macro invocation semi - depends on whether
+	 * there is a final ';' */
 	// convert path in expr to simple path (as that is used in macros)
 	AST::SimplePath macro_path = path.as_simple_path ();
 	if (macro_path.is_empty ())
@@ -11682,11 +11761,11 @@ Parser<ManagedTokenSource>::parse_path_based_stmt_or_expr (
 
 	    if (tree == nullptr)
 	      {
-		Error error (
-		  t3->get_locus (),
-		  "failed to parse token tree for macro invocation (or semi) - "
-		  "found %qs",
-		  t3->get_token_description ());
+		Error error (t3->get_locus (),
+			     "failed to parse token tree for macro "
+			     "invocation (or semi) - "
+			     "found %qs",
+			     t3->get_token_description ());
 		add_error (std::move (error));
 
 		return ExprOrStmt::create_error ();
@@ -11710,9 +11789,9 @@ Parser<ManagedTokenSource>::parse_path_based_stmt_or_expr (
 
 	    /* with curly bracketed macros, assume it is a macro invocation
 	     * unless a semicolon is explicitly put at the end. this is not
-	     * necessarily true (i.e. context-dependence) and so may have to be
-	     * fixed up via HACKs in semantic analysis (by checking whether it
-	     * is the last elem in the vector). */
+	     * necessarily true (i.e. context-dependence) and so may have to
+	     * be fixed up via HACKs in semantic analysis (by checking whether
+	     * it is the last elem in the vector). */
 
 	    AST::DelimTokenTree delim_tok_tree (type, std::move (token_trees),
 						tok_tree_loc);
@@ -11767,8 +11846,8 @@ Parser<ManagedTokenSource>::parse_path_based_stmt_or_expr (
 
 	if (not_a_block)
 	  {
-	    /* assume struct expr struct (as struct-enum disambiguation requires
-	     * name lookup) again, make statement if final ';' */
+	    /* assume struct expr struct (as struct-enum disambiguation
+	     * requires name lookup) again, make statement if final ';' */
 	    expr = parse_struct_expr_struct_partial (std::move (path),
 						     std::move (outer_attrs));
 	    if (expr == nullptr)
@@ -11806,8 +11885,8 @@ Parser<ManagedTokenSource>::parse_path_based_stmt_or_expr (
 	return ExprOrStmt (std::move (expr));
       }
       case LEFT_PAREN: {
-	/* assume struct expr tuple (as struct-enum disambiguation requires name
-	 * lookup) again, make statement if final ';' */
+	/* assume struct expr tuple (as struct-enum disambiguation requires
+	 * name lookup) again, make statement if final ';' */
 	std::unique_ptr<AST::CallExpr> struct_expr
 	  = parse_struct_expr_tuple_partial (std::move (path),
 					     std::move (outer_attrs));
@@ -11927,8 +12006,8 @@ Parser<ManagedTokenSource>::parse_struct_expr_field ()
 					      t->get_locus ()));
       }
     case DOT_DOT:
-      /* this is a struct base and can't be parsed here, so just return nothing
-       * without erroring */
+      /* this is a struct base and can't be parsed here, so just return
+       * nothing without erroring */
 
       return nullptr;
     default:
@@ -12031,8 +12110,8 @@ Parser<ManagedTokenSource>::parse_macro_invocation_maybe_semi (
       /* with curly bracketed macros, assume it is a macro invocation unless
        * a semicolon is explicitly put at the end. this is not necessarily
        * true (i.e. context-dependence) and so may have to be fixed up via
-       * HACKs in semantic analysis (by checking whether it is the last elem in
-       * the vector). */
+       * HACKs in semantic analysis (by checking whether it is the last elem
+       * in the vector). */
 
       AST::DelimTokenTree delim_tok_tree (type, std::move (token_trees),
 					  tok_tree_loc);
@@ -12193,8 +12272,8 @@ Parser<ManagedTokenSource>::skip_after_end_block ()
     }
 }
 
-/* Skips tokens until the end of the next block. i.e. assumes that the block has
- * not been entered yet. */
+/* Skips tokens until the end of the next block. i.e. assumes that the block
+ * has not been entered yet. */
 template <typename ManagedTokenSource>
 void
 Parser<ManagedTokenSource>::skip_after_next_block ()
@@ -12219,8 +12298,8 @@ Parser<ManagedTokenSource>::skip_after_next_block ()
   // otherwise, do nothing as EOF
 }
 
-/* Skips all tokens until ] (the end of an attribute) - does not skip the ] (as
- * designed for attribute body use) */
+/* Skips all tokens until ] (the end of an attribute) - does not skip the ]
+ * (as designed for attribute body use) */
 template <typename ManagedTokenSource>
 void
 Parser<ManagedTokenSource>::skip_after_end_attribute ()
@@ -12236,8 +12315,8 @@ Parser<ManagedTokenSource>::skip_after_end_attribute ()
   // Don't skip the RIGHT_SQUARE token
 }
 
-/* Pratt parser impl of parse_expr. FIXME: this is only provisional and probably
- * will be changed.
+/* Pratt parser impl of parse_expr. FIXME: this is only provisional and
+ * probably will be changed.
  * FIXME: this may only parse expressions without blocks as they are the only
  * expressions to have precedence? */
 template <typename ManagedTokenSource>
@@ -12469,9 +12548,9 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
 	      return nullptr;
 	  // can only apply to integer and float expressions
 	  if (expr->get_type() != integer_type_node || expr->get_type() !=
-      float_type_node) { rust_error_at(tok->get_locus(), "operand of unary plus
-      must be int or float but it is %s", print_type(expr->get_type())); return
-      nullptr;
+      float_type_node) { rust_error_at(tok->get_locus(), "operand of unary
+      plus must be int or float but it is %s", print_type(expr->get_type()));
+      return nullptr;
 	  }
 
 	  return Tree(expr, tok->get_locus());
@@ -12490,15 +12569,16 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
 	// can only apply to integer and float expressions
 	/*if (expr.get_type() != integer_type_node || expr.get_type() !=
 	float_type_node) { rust_error_at(tok->get_locus(), "operand of unary
-	minus must be int or float but it is %s", print_type(expr.get_type()));
-	    return Tree::error();
+	minus must be int or float but it is %s",
+	print_type(expr.get_type())); return Tree::error();
 	}*/
 	/* FIXME: when implemented the "get type" method on expr, ensure it is
 	 * int or float type (except unsigned int). Actually, this would
-	 * probably have to be done in semantic analysis (as type checking). */
+	 * probably have to be done in semantic analysis (as type checking).
+	 */
 
-	/* FIXME: allow outer attributes on these expressions by having an outer
-	 * attrs parameter in function*/
+	/* FIXME: allow outer attributes on these expressions by having an
+	 * outer attrs parameter in function*/
 	return std::unique_ptr<AST::NegationExpr> (
 	  new AST::NegationExpr (std::move (expr), NegationOperator::NEGATE,
 				 std::move (outer_attrs), tok->get_locus ()));
@@ -12529,8 +12609,8 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
 				 std::move (outer_attrs), tok->get_locus ()));
       }
       case ASTERISK: {
-	/* pointer dereference only - HACK: as struct expressions should always
-	 * be value expressions, cannot be dereferenced */
+	/* pointer dereference only - HACK: as struct expressions should
+	 * always be value expressions, cannot be dereferenced */
 	ParseRestrictions entered_from_unary;
 	entered_from_unary.entered_from_unary = true;
 	entered_from_unary.can_be_struct_expr = false;
@@ -12620,7 +12700,8 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
 	  "token is '%s'",
 	  lexer.peek_token ()->get_token_description ());
 
-	// HACK: always make "self" by itself a path (regardless of next tokens)
+	// HACK: always make "self" by itself a path (regardless of next
+	// tokens)
 	if (tok->get_id () == SELF && path.is_single_segment ())
 	  {
 	    // HACK: add outer attrs to path
@@ -12742,8 +12823,8 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
 }
 
 /* Called for each token that can appear in infix (between) position. Can be
- * operators or other punctuation. Returns a function pointer to member function
- * that implements the left denotation for the token given. */
+ * operators or other punctuation. Returns a function pointer to member
+ * function that implements the left denotation for the token given. */
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::Expr>
 Parser<ManagedTokenSource>::left_denotation (const_TokenPtr tok,
@@ -12773,7 +12854,8 @@ Parser<ManagedTokenSource>::left_denotation (const_TokenPtr tok,
     case MINUS:
       // difference expression - binary infix
       /*return parse_binary_minus_expr (tok, std::move (left),
-				      std::move (outer_attrs), restrictions);*/
+				      std::move (outer_attrs),
+	 restrictions);*/
       return parse_arithmetic_or_logical_expr (
 	tok, std::move (left), std::move (outer_attrs),
 	ArithmeticOrLogicalOperator::SUBTRACT, restrictions);
@@ -12836,7 +12918,8 @@ Parser<ManagedTokenSource>::left_denotation (const_TokenPtr tok,
     case EQUAL_EQUAL:
       // equal to expression - binary infix (no associativity)
       /*return parse_binary_equal_expr (tok, std::move (left),
-				      std::move (outer_attrs), restrictions);*/
+				      std::move (outer_attrs),
+	 restrictions);*/
       return parse_comparison_expr (tok, std::move (left),
 				    std::move (outer_attrs),
 				    ComparisonOperator::EQUAL, restrictions);
@@ -12899,7 +12982,8 @@ Parser<ManagedTokenSource>::left_denotation (const_TokenPtr tok,
       return parse_type_cast_expr (tok, std::move (left),
 				   std::move (outer_attrs), restrictions);
     case EQUAL:
-      // assignment expression - binary infix (note right-to-left associativity)
+      // assignment expression - binary infix (note right-to-left
+      // associativity)
       return parse_assig_expr (tok, std::move (left), std::move (outer_attrs),
 			       restrictions);
     case PLUS_EQ:
@@ -12998,7 +13082,8 @@ Parser<ManagedTokenSource>::left_denotation (const_TokenPtr tok,
       return parse_range_inclusive_expr (tok, std::move (left),
 					 std::move (outer_attrs), restrictions);
     case SCOPE_RESOLUTION:
-      // path expression - binary infix? FIXME should this even be parsed here?
+      // path expression - binary infix? FIXME should this even be parsed
+      // here?
       add_error (
 	Error (tok->get_locus (),
 	       "found scope resolution operator in left denotation "
@@ -13375,8 +13460,8 @@ get_lbp_for_comparison_expr (AST::ComparisonExpr::ExprType expr_type)
 }
 
 /* Parses a ComparisonExpr of given type and LBP. TODO find a way to only
- * specify one and have the other looked up - e.g. specify ExprType and binding
- * power is looked up? */
+ * specify one and have the other looked up - e.g. specify ExprType and
+ * binding power is looked up? */
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::ComparisonExpr>
 Parser<ManagedTokenSource>::parse_comparison_expr (
@@ -14093,8 +14178,8 @@ Parser<ManagedTokenSource>::parse_field_access_expr (
   const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> struct_expr,
   AST::AttrVec outer_attrs, ParseRestrictions restrictions ATTRIBUTE_UNUSED)
 {
-  /* get field name identifier (assume that this is a field access expr and not
-   * await, for instance) */
+  /* get field name identifier (assume that this is a field access expr and
+   * not await, for instance) */
   const_TokenPtr ident_tok = expect_token (IDENTIFIER);
   if (ident_tok == nullptr)
     return nullptr;
@@ -14254,7 +14339,8 @@ Parser<ManagedTokenSource>::parse_macro_invocation_partial (
     std::move (outer_attrs), macro_locus, restrictions.expr_can_be_stmt));
 }
 
-/* Parses a struct expr struct with a path in expression already parsed (but not
+/* Parses a struct expr struct with a path in expression already parsed (but
+ * not
  * '{' token). */
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::StructExprStruct>
@@ -14387,7 +14473,8 @@ Parser<ManagedTokenSource>::parse_struct_expr_struct_partial (
     }
 }
 
-/* Parses a struct expr tuple with a path in expression already parsed (but not
+/* Parses a struct expr tuple with a path in expression already parsed (but
+ * not
  * '(' token).
  * FIXME: this currently outputs a call expr, as they cannot be disambiguated.
  * A better solution would be to just get this to call that function directly.
@@ -14413,9 +14500,8 @@ Parser<ManagedTokenSource>::parse_struct_expr_tuple_partial (
       std::unique_ptr<AST::Expr> expr = parse_expr ();
       if (expr == nullptr)
 	{
-	  Error error (
-	    t->get_locus (),
-	    "failed to parse expression in struct (or enum) expression tuple");
+	  Error error (t->get_locus (), "failed to parse expression in "
+					"struct (or enum) expression tuple");
 	  add_error (std::move (error));
 
 	  return nullptr;
@@ -14445,9 +14531,9 @@ Parser<ManagedTokenSource>::parse_struct_expr_tuple_partial (
 		       std::move (outer_attrs), path_locus));
 }
 
-/* Parses a path in expression with the first token passed as a parameter (as it
- * is skipped in token stream). Note that this only parses segment-first paths,
- * not global ones. */
+/* Parses a path in expression with the first token passed as a parameter (as
+ * it is skipped in token stream). Note that this only parses segment-first
+ * paths, not global ones. */
 template <typename ManagedTokenSource>
 AST::PathInExpression
 Parser<ManagedTokenSource>::parse_path_in_expression_pratt (const_TokenPtr tok)
@@ -14498,8 +14584,8 @@ Parser<ManagedTokenSource>::parse_path_in_expression_pratt (const_TokenPtr tok)
   // parse required initial segment
   AST::PathExprSegment initial_segment (initial_str, tok->get_locus ());
   // parse generic args (and turbofish), if they exist
-  /* use lookahead to determine if they actually exist (don't want to accidently
-   * parse over next ident segment) */
+  /* use lookahead to determine if they actually exist (don't want to
+   * accidently parse over next ident segment) */
   if (lexer.peek_token ()->get_id () == SCOPE_RESOLUTION
       && lexer.peek_token (1)->get_id () == LEFT_ANGLE)
     {
@@ -14564,7 +14650,8 @@ std::unique_ptr<AST::ClosureExpr>
 Parser<ManagedTokenSource>::parse_closure_expr_pratt (const_TokenPtr tok,
 						      AST::AttrVec outer_attrs)
 {
-  // TODO: does this need pratt parsing (for precedence)? probably not, but idk
+  // TODO: does this need pratt parsing (for precedence)? probably not, but
+  // idk
   Location locus = tok->get_locus ();
   bool has_move = false;
   if (tok->get_id () == MOVE)
@@ -14741,10 +14828,11 @@ template <typename ManagedTokenSource>
 void
 Parser<ManagedTokenSource>::debug_dump_lex_output (std::ostream &out)
 {
-  /* TODO: a better implementation of "lexer dump" (as in dump what was actually
-   * tokenised) would actually be to "write" a token to a file every time
-   * skip_token() here was called. This would reflect the parser modifications
-   * to the token stream, such as fixing the template angle brackets. */
+  /* TODO: a better implementation of "lexer dump" (as in dump what was
+   * actually tokenised) would actually be to "write" a token to a file every
+   * time skip_token() here was called. This would reflect the parser
+   * modifications to the token stream, such as fixing the template angle
+   * brackets. */
 
   const_TokenPtr tok = lexer.peek_token ();
 
diff --git a/gcc/testsuite/rust/compile/const_generics_1.rs b/gcc/testsuite/rust/compile/const_generics_1.rs
new file mode 100644
index 00000000000..bcad8ee6a19
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_1.rs
@@ -0,0 +1,19 @@
+// { dg-additional-options "-w" }
+
+// There are errors about unused generic parameters, but we can't handle that yet.
+// Still, this code is invalid Rust.
+
+mod sain {
+    struct Foo<const N: usize>;
+    struct Bar<T, const N: usize>;
+    struct Baz<'l, T, const N: usize>;
+}
+
+mod doux {
+    struct Foo<const N: usize = 15>;
+    struct Bar<T, const N: usize = { 14 * 2 }>;
+
+    const N_DEFAULT: usize = 3;
+
+    struct Baz<'l, T, const N: usize = N_DEFAULT>;
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_2.rs b/gcc/testsuite/rust/compile/const_generics_2.rs
new file mode 100644
index 00000000000..82d2676f7ee
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_2.rs
@@ -0,0 +1,3 @@
+struct Foo<const N>; // { dg-error "expecting .:. but .>. found" }
+struct Bar<const N: >; // { dg-error "unrecognised token .>. in type" }
+struct Baz<const N: usize = >; // { dg-error "invalid token for start of default value for const generic parameter" }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-15 17:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-15 17:03 [gcc/devel/rust/master] parser: Add base for parsing const generic parameters Thomas Schwinge

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