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

gcc/rust/ChangeLog:

        * backend/rust-compile-resolve-path.cc (ResolvePathRef::visit): Adapt 
visitor to lang item
        HIR::PathInExpressions.
        * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::visit): 
Likewise.
---
 gcc/rust/backend/rust-compile-resolve-path.cc | 22 +++++-
 .../typecheck/rust-hir-type-check-path.cc     | 78 ++++++++++++++++---
 2 files changed, 85 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc 
b/gcc/rust/backend/rust-compile-resolve-path.cc
index d248ee282a6..eb897b7ee20 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -35,15 +35,29 @@ namespace Compile {
 void
 ResolvePathRef::visit (HIR::QualifiedPathInExpression &expr)
 {
-  resolved = resolve (expr.get_final_segment ().get_segment (),
-                     expr.get_mappings (), expr.get_locus (), true);
+  auto final_segment = HIR::PathIdentSegment::create_error ();
+  if (expr.is_lang_item ())
+    final_segment
+      = HIR::PathIdentSegment (LangItem::ToString (expr.get_lang_item ()));
+  else
+    final_segment = expr.get_final_segment ().get_segment ();
+
+  resolved
+    = resolve (final_segment, expr.get_mappings (), expr.get_locus (), true);
 }
 
 void
 ResolvePathRef::visit (HIR::PathInExpression &expr)
 {
-  resolved = resolve (expr.get_final_segment ().get_segment (),
-                     expr.get_mappings (), expr.get_locus (), false);
+  auto final_segment = HIR::PathIdentSegment::create_error ();
+  if (expr.is_lang_item ())
+    final_segment
+      = HIR::PathIdentSegment (LangItem::ToString (expr.get_lang_item ()));
+  else
+    final_segment = expr.get_final_segment ().get_segment ();
+
+  resolved
+    = resolve (final_segment, expr.get_mappings (), expr.get_locus (), true);
 }
 
 tree
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 4c7dec1dea3..68b33d1a05d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -16,6 +16,9 @@
 // along with GCC; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
+#include "rust-diagnostics.h"
+#include "rust-hir-map.h"
+#include "rust-hir-path.h"
 #include "rust-hir-type-check-expr.h"
 #include "rust-hir-type-check-type.h"
 #include "rust-hir-type-check-item.h"
@@ -24,6 +27,7 @@
 #include "rust-hir-path-probe.h"
 #include "rust-type-util.h"
 #include "rust-hir-type-bounds.h"
+#include "rust-hir-item.h"
 #include "rust-session-manager.h"
 #include "rust-immutable-name-resolution-context.h"
 
@@ -179,20 +183,72 @@ void
 TypeCheckExpr::visit (HIR::PathInExpression &expr)
 {
   NodeId resolved_node_id = UNKNOWN_NODEID;
-  size_t offset = -1;
-  TyTy::BaseType *tyseg = resolve_root_path (expr, &offset, &resolved_node_id);
-  if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
-    return;
-
-  bool fully_resolved = offset == expr.get_segments ().size ();
-  if (fully_resolved)
+  if (expr.is_lang_item ())
     {
-      infered = tyseg;
-      return;
+      auto lookup
+       = Analysis::Mappings::get ().get_lang_item_node (expr.get_lang_item ());
+      auto hir_id = mappings.lookup_node_to_hir (lookup);
+
+      // We can type resolve the path in expression easily as it is a lang
+      // item path, but we still need to setup the various generics and
+      // substitutions
+
+      // FIXME: We probably need to check *if* the type needs substitutions
+      // or not
+      if (LangItem::IsEnumVariant (expr.get_lang_item ()))
+       {
+         std::pair<HIR::Enum *, HIR::EnumItem *> enum_item_lookup
+           = mappings.lookup_hir_enumitem (*hir_id);
+         bool enum_item_ok = enum_item_lookup.first != nullptr
+                             && enum_item_lookup.second != nullptr;
+         rust_assert (enum_item_ok);
+
+         HirId variant_id
+           = enum_item_lookup.second->get_mappings ().get_hirid ();
+
+         HIR::EnumItem *enum_item = enum_item_lookup.second;
+         resolved_node_id = enum_item->get_mappings ().get_nodeid ();
+
+         // insert the id of the variant we are resolved to
+         context->insert_variant_definition (expr.get_mappings ().get_hirid (),
+                                             variant_id);
+
+         query_type (variant_id, &infered);
+         infered = SubstMapper::InferSubst (infered, expr.get_locus ());
+       }
+      else
+       {
+         TyTy::BaseType *resolved = nullptr;
+         context->lookup_type (*hir_id, &resolved);
+
+         rust_assert (resolved);
+
+         query_type (*hir_id, &infered);
+
+         infered = SubstMapper::InferSubst (resolved, expr.get_locus ());
+       }
+
+      // FIXME: also we probably need to insert resolved types in the name
+      // resolver here
     }
+  else
+    {
+      size_t offset = -1;
+      TyTy::BaseType *tyseg
+       = resolve_root_path (expr, &offset, &resolved_node_id);
+      if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
+       return;
+
+      bool fully_resolved = offset == expr.get_segments ().size ();
+      if (fully_resolved)
+       {
+         infered = tyseg;
+         return;
+       }
 
-  resolve_segments (resolved_node_id, expr.get_segments (), offset, tyseg,
-                   expr.get_mappings (), expr.get_locus ());
+      resolve_segments (resolved_node_id, expr.get_segments (), offset, tyseg,
+                       expr.get_mappings (), expr.get_locus ());
+    }
 }
 
 TyTy::BaseType *
-- 
2.45.2

Reply via email to