]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Prevent forward declaration in type parameters
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Wed, 23 Apr 2025 12:40:22 +0000 (14:40 +0200)
committerP-E-P <32375388+P-E-P@users.noreply.github.com>
Thu, 24 Apr 2025 09:46:13 +0000 (09:46 +0000)
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.patry@embecosm.com>
gcc/rust/resolve/rust-default-resolver.cc
gcc/rust/resolve/rust-default-resolver.h
gcc/rust/resolve/rust-forever-stack.h
gcc/rust/resolve/rust-late-name-resolver-2.0.cc

index 58e477660cdc96745987f4a9bb5e0860a51e72cc..1ec38bae4d7b5b4acc5367c3f8dd09dc524977bc 100644 (file)
@@ -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
index eb08dc87fead934296c7ee19d5f649d8bf4a3156..9b1580165fb6d5a7ff4a4965d3c86a196baf57fd 100644 (file)
@@ -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;
index a2848b1d015db166f4472709621016fd3b4d7817..3ca6e286e5fcc21a13512f6947f3588757c61554 100644 (file)
@@ -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
index 59aa4a8f6649ca9867123bc2b2bd23c15788a918..a86f196a16a66d9fb6b9a50d25b70e2e9e5b39a9 100644 (file)
@@ -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 ()));
 }