From: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>

gcc/rust/ChangeLog:

        * resolve/rust-default-resolver.cc (DefaultResolver::visit): Add visit
        function for TypeParam.
        * resolve/rust-default-resolver.h: Add function prototype.
        * resolve/rust-forever-stack.h: Add function to check for forward
        declaration ban.
        * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Check forward
        declarations.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>
---
 gcc/rust/resolve/rust-default-resolver.cc       |  8 ++++++++
 gcc/rust/resolve/rust-default-resolver.h        |  2 ++
 gcc/rust/resolve/rust-forever-stack.h           | 15 +++++++++++++++
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc |  8 ++++++++
 4 files changed, 33 insertions(+)

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index 7528e7950e6..480034c8974 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -179,5 +179,13 @@ DefaultResolver::visit (AST::StaticItem &item)
   ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis);
 }
 
+void
+DefaultResolver::visit (AST::TypeParam &param)
+{
+  auto expr_vis = [this, &param] () { AST::DefaultASTVisitor::visit (param); };
+
+  ctx.scoped (Rib::Kind::ForwardTypeParamBan, param.get_node_id (), expr_vis);
+}
+
 } // namespace Resolver2_0
 } // namespace Rust
diff --git a/gcc/rust/resolve/rust-default-resolver.h 
b/gcc/rust/resolve/rust-default-resolver.h
index 587d7d45803..2a987efdf5c 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -50,6 +50,8 @@ public:
   void visit (AST::InherentImpl &) override;
   void visit (AST::TraitImpl &) override;
 
+  void visit (AST::TypeParam &) override;
+
   // type dec nodes, which visit their fields or variants by default
   void visit (AST::StructStruct &) override;
   void visit (AST::TupleStruct &) override;
diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 75d8c1d9b59..81468e5c386 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -831,6 +831,21 @@ private:
   tl::optional<Node &> dfs_node (Node &starting_point, NodeId to_find);
   tl::optional<const Node &> dfs_node (const Node &starting_point,
                                       NodeId to_find) const;
+
+public:
+  bool forward_declared (NodeId definition, NodeId usage)
+  {
+    if (peek ().kind != Rib::Kind::ForwardTypeParamBan)
+      return false;
+
+    const auto &definition_rib = dfs_rib (cursor (), definition);
+
+    if (!definition_rib)
+      return false;
+
+    return (definition_rib
+           && definition_rib.value ().kind == Rib::Kind::ForwardTypeParamBan);
+  }
 };
 
 } // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index e0cd9515180..48e33c097de 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -401,6 +401,14 @@ Late::visit (AST::TypePath &type)
       return;
     }
 
+  if (ctx.types.forward_declared (resolved->get_node_id (),
+                                 type.get_node_id ()))
+    {
+      rust_error_at (type.get_locus (), ErrorCode::E0128,
+                    "type parameters with a default cannot use forward "
+                    "declared identifiers");
+    }
+
   ctx.map_usage (Usage (type.get_node_id ()),
                 Definition (resolved->get_node_id ()));
 }
-- 
2.49.0

Reply via email to