]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: ast: Move rust-path implementation out of rust-ast
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Mon, 3 Apr 2023 15:22:57 +0000 (17:22 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:28:43 +0000 (18:28 +0100)
Move rust-path implementation details out of rust-ast.cc file. This will
hopefully decrease compile time and make things clearer.

gcc/rust/ChangeLog:

* Make-lang.in: Add new file for rust-path implementation.
* ast/rust-ast.cc (PathInExpression::as_string): Move function
to the new file.
(PathPattern::as_string): Likewise.
(QualifiedPathInExpression::as_string): Likewise.
(ConstGenericParam::as_string): Likewise.
(QualifiedPathInType::as_string): Likewise.
(TypePath::as_string): Likewise.
(PathPattern::convert_to_simple_path): Likewise.
(TypePath::as_simple_path): Likewise.
(PathExprSegment::as_string): Likewise.
(GenericArgs::as_string): Likewise.
(GenericArgsBinding::as_string): Likewise.
(TypePath::to_trait_bound): Likewise.
(TypePathSegmentGeneric::as_string): Likewise.
(TypePathFunction::as_string): Likewise.
(TypePathSegmentFunction::as_string): Likewise.
(ConstGenericParam::accept_vis): Likewise.
(PathInExpression::accept_vis): Likewise.
(TypePathSegment::accept_vis): Likewise.
(TypePathSegmentGeneric::accept_vis): Likewise.
(TypePathSegmentFunction::accept_vis): Likewise.
(TypePath::accept_vis): Likewise.
(QualifiedPathInExpression::accept_vis): Likewise.
(QualifiedPathInType::accept_vis): Likewise.
(GenericArg::disambiguate_to_const): Likewise.
(GenericArg::disambiguate_to_type): Likewise.
* ast/rust-path.cc: New file.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
gcc/rust/Make-lang.in
gcc/rust/ast/rust-ast.cc
gcc/rust/ast/rust-path.cc [new file with mode: 0644]

index bf6d3f0766497abd1c4ad6bc6b7cc182edcfc300..2d522c78b91fae3b21d3a664d84ad9cac3c81f50 100644 (file)
@@ -73,6 +73,7 @@ GRS_OBJS = \
     rust/rust-cfg-parser.o \
     rust/rust-parse.o \
     rust/rust-ast.o \
+    rust/rust-path.o \
     rust/rust-ast-fragment.o \
     rust/rust-ast-dump.o \
     rust/rust-ast-tokenstream.o \
index 4a366a540d4b80c95d0304be8a39cf1aa9b63851..b483c83ae850aa6c8f085c413af1befb7ccebbe6 100644 (file)
@@ -1356,17 +1356,6 @@ MacroInvocData::as_string () const
   return path.as_string () + "!" + token_tree.as_string ();
 }
 
-std::string
-PathInExpression::as_string () const
-{
-  std::string str;
-
-  if (has_opening_scope_resolution)
-    str = "::";
-
-  return str + PathPattern::as_string ();
-}
-
 std::string
 ExprStmtWithBlock::as_string () const
 {
@@ -1437,20 +1426,6 @@ ClosureExprInnerTyped::as_string () const
   return str;
 }
 
-std::string
-PathPattern::as_string () const
-{
-  std::string str;
-
-  for (const auto &segment : segments)
-    str += segment.as_string () + "::";
-
-  // basically a hack - remove last two characters of string (remove final ::)
-  str.erase (str.length () - 2);
-
-  return str;
-}
-
 std::string
 QualifiedPathType::as_string () const
 {
@@ -1463,12 +1438,6 @@ QualifiedPathType::as_string () const
   return str + ">";
 }
 
-std::string
-QualifiedPathInExpression::as_string () const
-{
-  return path_type.as_string () + "::" + PathPattern::as_string ();
-}
-
 std::string
 BorrowExpr::as_string () const
 {
@@ -2372,38 +2341,12 @@ LifetimeParam::as_string () const
   return str;
 }
 
-std::string
-ConstGenericParam::as_string () const
-{
-  std::string str ("ConstGenericParam: ");
-  str += "const " + name + ": " + type->as_string ();
-
-  if (has_default_value ())
-    str += " = " + get_default_value ().as_string ();
-
-  return str;
-}
-
 std::string
 MacroMatchFragment::as_string () const
 {
   return "$" + ident + ": " + frag_spec.as_string ();
 }
 
-std::string
-QualifiedPathInType::as_string () const
-{
-  /* TODO: this may need adjusting if segments (e.g. with functions) can't be
-   * literalised */
-  std::string str = path_type.as_string ();
-
-  str += "::" + associated_segment->as_string ();
-  for (const auto &segment : segments)
-    str += "::" + segment->as_string ();
-
-  return str;
-}
-
 std::string
 MacroMatchRepetition::as_string () const
 {
@@ -2467,25 +2410,6 @@ Lifetime::as_string () const
     }
 }
 
-std::string
-TypePath::as_string () const
-{
-  /* TODO: this may need to be rewritten if a segment (e.g. function) can't be
-   * literalised */
-  std::string str;
-
-  if (has_opening_scope_resolution)
-    str = "::";
-
-  for (const auto &segment : segments)
-    str += segment->as_string () + "::";
-
-  // kinda hack - remove last 2 '::' characters
-  str.erase (str.length () - 2);
-
-  return str;
-}
-
 std::string
 TypeParam::as_string () const
 {
@@ -2519,136 +2443,6 @@ TypeParam::as_string () const
   return str;
 }
 
-SimplePath
-PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const
-{
-  if (!has_segments ())
-    return SimplePath::create_empty ();
-
-  // create vector of reserved size (to minimise reallocations)
-  std::vector<SimplePathSegment> simple_segments;
-  simple_segments.reserve (segments.size ());
-
-  for (const auto &segment : segments)
-    {
-      // return empty path if doesn't meet simple path segment requirements
-      if (segment.is_error () || segment.has_generic_args ()
-         || segment.as_string () == "Self")
-       return SimplePath::create_empty ();
-
-      // create segment and add to vector
-      std::string segment_str = segment.as_string ();
-      simple_segments.push_back (
-       SimplePathSegment (std::move (segment_str), segment.get_locus ()));
-    }
-
-  // kind of a HACK to get locus depending on opening scope resolution
-  Location locus = Linemap::unknown_location ();
-  if (with_opening_scope_resolution)
-    locus = simple_segments[0].get_locus () - 2; // minus 2 chars for ::
-  else
-    locus = simple_segments[0].get_locus ();
-  // FIXME: this hack probably doesn't actually work
-
-  return SimplePath (std::move (simple_segments), with_opening_scope_resolution,
-                    locus);
-}
-
-SimplePath
-TypePath::as_simple_path () const
-{
-  if (segments.empty ())
-    return SimplePath::create_empty ();
-
-  // create vector of reserved size (to minimise reallocations)
-  std::vector<SimplePathSegment> simple_segments;
-  simple_segments.reserve (segments.size ());
-
-  for (const auto &segment : segments)
-    {
-      // return empty path if doesn't meet simple path segment requirements
-      if (segment == nullptr || segment->is_error ()
-         || !segment->is_ident_only () || segment->as_string () == "Self")
-       return SimplePath::create_empty ();
-
-      // create segment and add to vector
-      std::string segment_str = segment->as_string ();
-      simple_segments.push_back (
-       SimplePathSegment (std::move (segment_str), segment->get_locus ()));
-    }
-
-  return SimplePath (std::move (simple_segments), has_opening_scope_resolution,
-                    locus);
-}
-
-std::string
-PathExprSegment::as_string () const
-{
-  // TODO: rewrite dump to work with non-literalisable types
-  std::string ident_str = segment_name.as_string ();
-  if (has_generic_args ())
-    ident_str += "::<" + generic_args.as_string () + ">";
-
-  return ident_str;
-}
-
-std::string
-GenericArgs::as_string () const
-{
-  std::string args;
-
-  // lifetime args
-  if (!lifetime_args.empty ())
-    {
-      auto i = lifetime_args.begin ();
-      auto e = lifetime_args.end ();
-
-      for (; i != e; i++)
-       {
-         args += (*i).as_string ();
-         if (e != i + 1)
-           args += ", ";
-       }
-    }
-
-  // type args
-  if (!generic_args.empty ())
-    {
-      auto i = generic_args.begin ();
-      auto e = generic_args.end ();
-
-      for (; i != e; i++)
-       {
-         args += (*i).as_string ();
-         if (e != i + 1)
-           args += ", ";
-       }
-    }
-
-  // binding args
-  if (!binding_args.empty ())
-    {
-      auto i = binding_args.begin ();
-      auto e = binding_args.end ();
-
-      for (; i != e; i++)
-       {
-         args += (*i).as_string ();
-         if (e != i + 1)
-           args += ", ";
-       }
-    }
-
-  return args;
-}
-
-std::string
-GenericArgsBinding::as_string () const
-{
-  // TODO: rewrite to work with non-literalisable types
-  return identifier + " = " + type->as_string ();
-}
-
 std::string
 ForLoopExpr::as_string () const
 {
@@ -2968,13 +2762,6 @@ LetStmt::as_string () const
   return str;
 }
 
-// hopefully definition here will prevent circular dependency issue
-TraitBound *
-TypePath::to_trait_bound (bool in_parens) const
-{
-  return new TraitBound (TypePath (*this), get_locus (), in_parens);
-}
-
 std::string
 InferredType::as_string () const
 {
@@ -3122,13 +2909,6 @@ ImplTraitTypeOneBound::as_string () const
   return str + trait_bound.as_string ();
 }
 
-std::string
-TypePathSegmentGeneric::as_string () const
-{
-  // TODO: rewrite to work with non-linearisable types
-  return TypePathSegment::as_string () + "<" + generic_args.as_string () + ">";
-}
-
 std::string
 TraitObjectTypeOneBound::as_string () const
 {
@@ -3144,40 +2924,6 @@ TraitObjectTypeOneBound::as_string () const
   return str;
 }
 
-std::string
-TypePathFunction::as_string () const
-{
-  // TODO: rewrite to work with non-linearisable types
-  std::string str ("(");
-
-  if (has_inputs ())
-    {
-      auto i = inputs.begin ();
-      auto e = inputs.end ();
-
-      for (; i != e; i++)
-       {
-         str += (*i)->as_string ();
-         if (e != i + 1)
-           str += ", ";
-       }
-    }
-
-  str += ")";
-
-  if (has_return_type ())
-    str += " -> " + return_type->as_string ();
-
-  return str;
-}
-
-std::string
-TypePathSegmentFunction::as_string () const
-{
-  // TODO: rewrite to work with non-linearisable types
-  return TypePathSegment::as_string () + function_path.as_string ();
-}
-
 std::string
 ArrayType::as_string () const
 {
@@ -4933,54 +4679,6 @@ LifetimeParam::accept_vis (ASTVisitor &vis)
   vis.visit (*this);
 }
 
-void
-ConstGenericParam::accept_vis (ASTVisitor &vis)
-{
-  vis.visit (*this);
-}
-
-void
-PathInExpression::accept_vis (ASTVisitor &vis)
-{
-  vis.visit (*this);
-}
-
-void
-TypePathSegment::accept_vis (ASTVisitor &vis)
-{
-  vis.visit (*this);
-}
-
-void
-TypePathSegmentGeneric::accept_vis (ASTVisitor &vis)
-{
-  vis.visit (*this);
-}
-
-void
-TypePathSegmentFunction::accept_vis (ASTVisitor &vis)
-{
-  vis.visit (*this);
-}
-
-void
-TypePath::accept_vis (ASTVisitor &vis)
-{
-  vis.visit (*this);
-}
-
-void
-QualifiedPathInExpression::accept_vis (ASTVisitor &vis)
-{
-  vis.visit (*this);
-}
-
-void
-QualifiedPathInType::accept_vis (ASTVisitor &vis)
-{
-  vis.visit (*this);
-}
-
 void
 LiteralExpr::accept_vis (ASTVisitor &vis)
 {
@@ -5839,29 +5537,5 @@ MetaWord::accept_vis (ASTVisitor &vis)
   vis.visit (*this);
 }
 
-GenericArg
-GenericArg::disambiguate_to_const () const
-{
-  rust_assert (get_kind () == Kind::Either);
-
-  // FIXME: is it fine to have no outer attributes?
-  return GenericArg::create_const (
-    std::unique_ptr<Expr> (new IdentifierExpr (path, {}, locus)));
-}
-
-GenericArg
-GenericArg::disambiguate_to_type () const
-{
-  rust_assert (get_kind () == Kind::Either);
-
-  auto segment = std::unique_ptr<TypePathSegment> (
-    new TypePathSegment (path, false, locus));
-  auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
-  segments.emplace_back (std::move (segment));
-
-  return GenericArg::create_type (
-    std::unique_ptr<Type> (new TypePath (std::move (segments), locus)));
-}
-
 } // namespace AST
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc
new file mode 100644 (file)
index 0000000..9a3489b
--- /dev/null
@@ -0,0 +1,360 @@
+/* General AST-related method implementations for Rust frontend.
+   Copyright (C) 2009-2023 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "rust-system.h"
+#include "rust-ast-full.h"
+#include "rust-diagnostics.h"
+#include "rust-ast-visitor.h"
+#include "rust-macro.h"
+#include "rust-session-manager.h"
+#include "rust-lex.h"
+#include "rust-parse.h"
+#include "rust-operators.h"
+
+namespace Rust {
+namespace AST {
+
+std::string
+GenericArgs::as_string () const
+{
+  std::string args;
+
+  // lifetime args
+  if (!lifetime_args.empty ())
+    {
+      auto i = lifetime_args.begin ();
+      auto e = lifetime_args.end ();
+
+      for (; i != e; i++)
+       {
+         args += (*i).as_string ();
+         if (e != i + 1)
+           args += ", ";
+       }
+    }
+
+  // type args
+  if (!generic_args.empty ())
+    {
+      auto i = generic_args.begin ();
+      auto e = generic_args.end ();
+
+      for (; i != e; i++)
+       {
+         args += (*i).as_string ();
+         if (e != i + 1)
+           args += ", ";
+       }
+    }
+
+  // binding args
+  if (!binding_args.empty ())
+    {
+      auto i = binding_args.begin ();
+      auto e = binding_args.end ();
+
+      for (; i != e; i++)
+       {
+         args += (*i).as_string ();
+         if (e != i + 1)
+           args += ", ";
+       }
+    }
+
+  return args;
+}
+
+GenericArg
+GenericArg::disambiguate_to_const () const
+{
+  rust_assert (get_kind () == Kind::Either);
+
+  // FIXME: is it fine to have no outer attributes?
+  return GenericArg::create_const (
+    std::unique_ptr<Expr> (new IdentifierExpr (path, {}, locus)));
+}
+
+GenericArg
+GenericArg::disambiguate_to_type () const
+{
+  rust_assert (get_kind () == Kind::Either);
+
+  auto segment = std::unique_ptr<TypePathSegment> (
+    new TypePathSegment (path, false, locus));
+  auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
+  segments.emplace_back (std::move (segment));
+
+  return GenericArg::create_type (
+    std::unique_ptr<Type> (new TypePath (std::move (segments), locus)));
+}
+
+std::string
+GenericArgsBinding::as_string () const
+{
+  // TODO: rewrite to work with non-literalisable types
+  return identifier + " = " + type->as_string ();
+}
+
+std::string
+ConstGenericParam::as_string () const
+{
+  std::string str ("ConstGenericParam: ");
+  str += "const " + name + ": " + type->as_string ();
+
+  if (has_default_value ())
+    str += " = " + get_default_value ().as_string ();
+
+  return str;
+}
+
+std::string
+PathExprSegment::as_string () const
+{
+  // TODO: rewrite dump to work with non-literalisable types
+  std::string ident_str = segment_name.as_string ();
+  if (has_generic_args ())
+    ident_str += "::<" + generic_args.as_string () + ">";
+
+  return ident_str;
+}
+
+std::string
+PathPattern::as_string () const
+{
+  std::string str;
+
+  for (const auto &segment : segments)
+    str += segment.as_string () + "::";
+
+  // basically a hack - remove last two characters of string (remove final ::)
+  str.erase (str.length () - 2);
+
+  return str;
+}
+
+SimplePath
+PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const
+{
+  if (!has_segments ())
+    return SimplePath::create_empty ();
+
+  // create vector of reserved size (to minimise reallocations)
+  std::vector<SimplePathSegment> simple_segments;
+  simple_segments.reserve (segments.size ());
+
+  for (const auto &segment : segments)
+    {
+      // return empty path if doesn't meet simple path segment requirements
+      if (segment.is_error () || segment.has_generic_args ()
+         || segment.as_string () == "Self")
+       return SimplePath::create_empty ();
+
+      // create segment and add to vector
+      std::string segment_str = segment.as_string ();
+      simple_segments.push_back (
+       SimplePathSegment (std::move (segment_str), segment.get_locus ()));
+    }
+
+  // kind of a HACK to get locus depending on opening scope resolution
+  Location locus = Linemap::unknown_location ();
+  if (with_opening_scope_resolution)
+    locus = simple_segments[0].get_locus () - 2; // minus 2 chars for ::
+  else
+    locus = simple_segments[0].get_locus ();
+  // FIXME: this hack probably doesn't actually work
+
+  return SimplePath (std::move (simple_segments), with_opening_scope_resolution,
+                    locus);
+}
+
+void
+PathInExpression::accept_vis (ASTVisitor &vis)
+{
+  vis.visit (*this);
+}
+
+std::string
+PathInExpression::as_string () const
+{
+  std::string str;
+
+  if (has_opening_scope_resolution)
+    str = "::";
+
+  return str + PathPattern::as_string ();
+}
+
+std::string
+TypePathSegmentGeneric::as_string () const
+{
+  // TODO: rewrite to work with non-linearisable types
+  return TypePathSegment::as_string () + "<" + generic_args.as_string () + ">";
+}
+
+std::string
+TypePathSegmentFunction::as_string () const
+{
+  // TODO: rewrite to work with non-linearisable types
+  return TypePathSegment::as_string () + function_path.as_string ();
+}
+
+std::string
+TypePath::as_string () const
+{
+  /* TODO: this may need to be rewritten if a segment (e.g. function) can't be
+   * literalised */
+  std::string str;
+
+  if (has_opening_scope_resolution)
+    str = "::";
+
+  for (const auto &segment : segments)
+    str += segment->as_string () + "::";
+
+  // kinda hack - remove last 2 '::' characters
+  str.erase (str.length () - 2);
+
+  return str;
+}
+
+SimplePath
+TypePath::as_simple_path () const
+{
+  if (segments.empty ())
+    return SimplePath::create_empty ();
+
+  // create vector of reserved size (to minimise reallocations)
+  std::vector<SimplePathSegment> simple_segments;
+  simple_segments.reserve (segments.size ());
+
+  for (const auto &segment : segments)
+    {
+      // return empty path if doesn't meet simple path segment requirements
+      if (segment == nullptr || segment->is_error ()
+         || !segment->is_ident_only () || segment->as_string () == "Self")
+       return SimplePath::create_empty ();
+
+      // create segment and add to vector
+      std::string segment_str = segment->as_string ();
+      simple_segments.push_back (
+       SimplePathSegment (std::move (segment_str), segment->get_locus ()));
+    }
+
+  return SimplePath (std::move (simple_segments), has_opening_scope_resolution,
+                    locus);
+}
+
+// hopefully definition here will prevent circular dependency issue
+TraitBound *
+TypePath::to_trait_bound (bool in_parens) const
+{
+  return new TraitBound (TypePath (*this), get_locus (), in_parens);
+}
+
+std::string
+TypePathFunction::as_string () const
+{
+  // TODO: rewrite to work with non-linearisable types
+  std::string str ("(");
+
+  if (has_inputs ())
+    {
+      auto i = inputs.begin ();
+      auto e = inputs.end ();
+
+      for (; i != e; i++)
+       {
+         str += (*i)->as_string ();
+         if (e != i + 1)
+           str += ", ";
+       }
+    }
+
+  str += ")";
+
+  if (has_return_type ())
+    str += " -> " + return_type->as_string ();
+
+  return str;
+}
+
+std::string
+QualifiedPathInExpression::as_string () const
+{
+  return path_type.as_string () + "::" + PathPattern::as_string ();
+}
+
+std::string
+QualifiedPathInType::as_string () const
+{
+  /* TODO: this may need adjusting if segments (e.g. with functions) can't be
+   * literalised */
+  std::string str = path_type.as_string ();
+
+  str += "::" + associated_segment->as_string ();
+  for (const auto &segment : segments)
+    str += "::" + segment->as_string ();
+
+  return str;
+}
+
+void
+ConstGenericParam::accept_vis (ASTVisitor &vis)
+{
+  vis.visit (*this);
+}
+
+void
+TypePathSegment::accept_vis (ASTVisitor &vis)
+{
+  vis.visit (*this);
+}
+
+void
+TypePathSegmentGeneric::accept_vis (ASTVisitor &vis)
+{
+  vis.visit (*this);
+}
+
+void
+TypePathSegmentFunction::accept_vis (ASTVisitor &vis)
+{
+  vis.visit (*this);
+}
+
+void
+TypePath::accept_vis (ASTVisitor &vis)
+{
+  vis.visit (*this);
+}
+
+void
+QualifiedPathInExpression::accept_vis (ASTVisitor &vis)
+{
+  vis.visit (*this);
+}
+
+void
+QualifiedPathInType::accept_vis (ASTVisitor &vis)
+{
+  vis.visit (*this);
+}
+
+} // namespace AST
+} // namespace Rust