From: Arthur Cohen <arthur.co...@embecosm.com>

gcc/rust/ChangeLog:

        * hir/tree/rust-hir-path.h: Adapt PathPattern to accept lang-item paths.
        * hir/tree/rust-hir-path.cc: Assert we are dealing with a segmented 
path, create lang-item
        constructors.
        * hir/tree/rust-hir.cc (PathPattern::convert_to_simple_path): Likewise.
---
 gcc/rust/hir/tree/rust-hir-path.cc | 20 +++++++
 gcc/rust/hir/tree/rust-hir-path.h  | 86 +++++++++++++++++++++++++++---
 gcc/rust/hir/tree/rust-hir.cc      |  6 +++
 3 files changed, 104 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/hir/tree/rust-hir-path.cc 
b/gcc/rust/hir/tree/rust-hir-path.cc
index 7db2b25b5aa..ee4a57294db 100644
--- a/gcc/rust/hir/tree/rust-hir-path.cc
+++ b/gcc/rust/hir/tree/rust-hir-path.cc
@@ -133,6 +133,8 @@ PathExprSegment::operator= (PathExprSegment const &other)
 void
 PathPattern::iterate_path_segments (std::function<bool (PathExprSegment &)> cb)
 {
+  rust_assert (kind == Kind::Segmented);
+
   for (auto it = segments.begin (); it != segments.end (); it++)
     {
       if (!cb (*it))
@@ -150,6 +152,15 @@ PathInExpression::PathInExpression (Analysis::NodeMapping 
mappings,
     has_opening_scope_resolution (has_opening_scope_resolution), locus (locus)
 {}
 
+PathInExpression::PathInExpression (Analysis::NodeMapping mappings,
+                                   LangItem::Kind lang_item, location_t locus,
+                                   bool has_opening_scope_resolution,
+                                   std::vector<AST::Attribute> outer_attrs)
+  : PathPattern (lang_item),
+    PathExpr (std::move (mappings), std::move (outer_attrs)),
+    has_opening_scope_resolution (has_opening_scope_resolution), locus (locus)
+{}
+
 bool
 PathInExpression::is_self () const
 
@@ -358,6 +369,15 @@ QualifiedPathInExpression::QualifiedPathInExpression (
     path_type (std::move (qual_path_type)), locus (locus)
 {}
 
+QualifiedPathInExpression::QualifiedPathInExpression (
+  Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
+  LangItem::Kind lang_item, location_t locus,
+  std::vector<AST::Attribute> outer_attrs)
+  : PathPattern (lang_item),
+    PathExpr (std::move (mappings), std::move (outer_attrs)),
+    path_type (std::move (qual_path_type)), locus (locus)
+{}
+
 QualifiedPathInType::QualifiedPathInType (
   Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
   std::unique_ptr<TypePathSegment> associated_segment,
diff --git a/gcc/rust/hir/tree/rust-hir-path.h 
b/gcc/rust/hir/tree/rust-hir-path.h
index bbb9c2d6077..c46f81e981c 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -19,6 +19,7 @@
 #ifndef RUST_HIR_PATH_H
 #define RUST_HIR_PATH_H
 
+#include "rust-hir-map.h"
 #include "rust-hir-simple-path.h"
 #include "rust-hir-type-no-bounds.h"
 #include "rust-hir-pattern-abstract.h"
@@ -230,15 +231,34 @@ public:
 // HIR node representing a pattern that involves a "path" - abstract base class
 class PathPattern : public Pattern
 {
+public:
+  enum class Kind
+  {
+    Segmented,
+    LangItem
+  };
+
+private:
   std::vector<PathExprSegment> segments;
+  tl::optional<LangItem::Kind> lang_item;
+  Kind kind;
 
 protected:
   PathPattern (std::vector<PathExprSegment> segments)
-    : segments (std::move (segments))
+    : segments (std::move (segments)), lang_item (tl::nullopt),
+      kind (Kind::Segmented)
+  {}
+
+  PathPattern (LangItem::Kind lang_item)
+    : segments ({}), lang_item (lang_item), kind (Kind::LangItem)
   {}
 
   // Returns whether path has segments.
-  bool has_segments () const { return !segments.empty (); }
+  bool has_segments () const
+  {
+    rust_assert (kind == Kind::Segmented);
+    return !segments.empty ();
+  }
 
   /* Converts path segments to their equivalent SimplePath segments if 
possible,
    * and creates a SimplePath from them. */
@@ -248,26 +268,61 @@ protected:
 public:
   /* Returns whether the path is a single segment (excluding qualified path
    * initial as segment). */
-  bool is_single_segment () const { return segments.size () == 1; }
+  bool is_single_segment () const
+  {
+    rust_assert (kind == Kind::Segmented);
+    return segments.size () == 1;
+  }
 
   std::string as_string () const override;
 
   void iterate_path_segments (std::function<bool (PathExprSegment &)> cb);
 
-  size_t get_num_segments () const { return segments.size (); }
+  size_t get_num_segments () const
+  {
+    rust_assert (kind == Kind::Segmented);
+    return segments.size ();
+  }
 
-  std::vector<PathExprSegment> &get_segments () { return segments; }
+  std::vector<PathExprSegment> &get_segments ()
+  {
+    rust_assert (kind == Kind::Segmented);
+    return segments;
+  }
 
-  const std::vector<PathExprSegment> &get_segments () const { return segments; 
}
+  const std::vector<PathExprSegment> &get_segments () const
+  {
+    rust_assert (kind == Kind::Segmented);
+    return segments;
+  }
 
-  PathExprSegment &get_root_seg () { return segments.at (0); }
+  PathExprSegment &get_root_seg ()
+  {
+    rust_assert (kind == Kind::Segmented);
+    return segments.at (0);
+  }
+
+  const PathExprSegment &get_final_segment () const
+  {
+    rust_assert (kind == Kind::Segmented);
+    return segments.back ();
+  }
 
-  const PathExprSegment &get_final_segment () const { return segments.back (); 
}
+  LangItem::Kind get_lang_item () const
+  {
+    rust_assert (kind == Kind::LangItem);
+
+    return *lang_item;
+  }
 
   PatternType get_pattern_type () const override final
   {
     return PatternType::PATH;
   }
+
+  bool is_lang_item () const { return kind == Kind::LangItem; }
+
+  Kind get_path_kind () const { return kind; }
 };
 
 /* HIR node representing a path-in-expression pattern (path that allows generic
@@ -288,6 +343,13 @@ public:
                    std::vector<AST::Attribute> outer_attrs
                    = std::vector<AST::Attribute> ());
 
+  // lang-item Constructor
+  PathInExpression (Analysis::NodeMapping mappings, LangItem::Kind kind,
+                   location_t locus = UNDEF_LOCATION,
+                   bool has_opening_scope_resolution = false,
+                   std::vector<AST::Attribute> outer_attrs
+                   = std::vector<AST::Attribute> ());
+
   // Creates an error state path in expression.
   static PathInExpression create_error ()
   {
@@ -701,6 +763,14 @@ public:
                             std::vector<AST::Attribute> outer_attrs
                             = std::vector<AST::Attribute> ());
 
+  // lang-item constructor
+  QualifiedPathInExpression (Analysis::NodeMapping mappings,
+                            QualifiedPathType qual_path_type,
+                            LangItem::Kind lang_item,
+                            location_t locus = UNDEF_LOCATION,
+                            std::vector<AST::Attribute> outer_attrs
+                            = std::vector<AST::Attribute> ());
+
   location_t get_locus () const override final { return locus; }
 
   void accept_vis (HIRFullVisitor &vis) override;
diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index da1c8b9ab1b..22b0867305c 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -19,6 +19,7 @@
 #include "rust-ast-full.h"
 #include "rust-hir-expr.h"
 #include "rust-hir-full.h"
+#include "rust-hir-path.h"
 #include "rust-hir-visitor.h"
 #include "rust-diagnostics.h"
 
@@ -1210,6 +1211,9 @@ ClosureExpr::as_string () const
 std::string
 PathPattern::as_string () const
 {
+  if (is_lang_item ())
+    return LangItem::PrettyString (*lang_item);
+
   std::string str;
 
   for (const auto &segment : segments)
@@ -2187,6 +2191,8 @@ TypeParam::as_string () const
 AST::SimplePath
 PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const
 {
+  rust_assert (kind == Kind::Segmented);
+
   if (!has_segments ())
     {
       return AST::SimplePath::create_empty ();
-- 
2.45.2

Reply via email to