https://gcc.gnu.org/g:fb346fab74307399234e1bf8891332943eabb8d6

commit fb346fab74307399234e1bf8891332943eabb8d6
Author: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>
Date:   Tue Oct 24 17:13:13 2023 +0200

    Emit an error on associated const without values
    
    Associated const with no value that are not in trait impl are prohibited.
    
    gcc/rust/ChangeLog:
    
            * checks/errors/rust-ast-validation.cc (ASTValidation::check): 
Launch
            check over the whole given crate.
            (ASTValidation::visit): Implement visitor for some members of the 
ast.
            * checks/errors/rust-ast-validation.h: Update some prototype 
according
            to implemented visitor functions. Also add a context tracker.
    
    Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>

Diff:
---
 gcc/rust/checks/errors/rust-ast-validation.cc | 33 ++++++++++++++++++++++++++-
 gcc/rust/checks/errors/rust-ast-validation.h  | 18 +++++++++++++--
 2 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc 
b/gcc/rust/checks/errors/rust-ast-validation.cc
index 199b2f9910db..c9498a4b435e 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.cc
+++ b/gcc/rust/checks/errors/rust-ast-validation.cc
@@ -17,6 +17,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-ast-validation.h"
+#include "rust-diagnostics.h"
 
 namespace Rust {
 
@@ -37,14 +38,44 @@ ASTValidation::visit (std::unique_ptr<T> &node)
 void
 ASTValidation::check (AST::Crate &crate)
 {
+  push_context (Context::CRATE);
   for (auto &item : crate.items)
     {
       visit (item);
     }
+  pop_context ();
 }
 
 void
 ASTValidation::visit (AST::InherentImpl &impl)
-{}
+{
+  push_context (Context::INHERENT_IMPL);
+  for (auto &item : impl.get_impl_items ())
+    {
+      visit (item);
+    }
+  pop_context ();
+}
+
+void
+ASTValidation::visit (AST::TraitImpl &impl)
+{
+  push_context (Context::TRAIT_IMPL);
+  for (auto &item : impl.get_impl_items ())
+    {
+      visit (item);
+    }
+  pop_context ();
+}
+
+void
+ASTValidation::visit (AST::ConstantItem &const_item)
+{
+  if (!const_item.has_expr () && context.back () != Context::TRAIT_IMPL)
+    {
+      rust_error_at (const_item.get_locus (),
+                    "associated constant in %<impl%> without body");
+    }
+}
 
 } // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-ast-validation.h 
b/gcc/rust/checks/errors/rust-ast-validation.h
index 982a9291d128..ada01b1ae3a6 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.h
+++ b/gcc/rust/checks/errors/rust-ast-validation.h
@@ -124,7 +124,7 @@ public:
   void visit (AST::EnumItemDiscriminant &item) override {}
   void visit (AST::Enum &enum_item) override {}
   void visit (AST::Union &union_item) override {}
-  void visit (AST::ConstantItem &const_item) override {}
+  void visit (AST::ConstantItem &const_item) override;
   void visit (AST::StaticItem &static_item) override {}
   void visit (AST::TraitItemFunc &item) override {}
   void visit (AST::TraitItemMethod &item) override {}
@@ -132,7 +132,7 @@ public:
   void visit (AST::TraitItemType &item) override {}
   void visit (AST::Trait &trait) override {}
   void visit (AST::InherentImpl &impl) override;
-  void visit (AST::TraitImpl &impl) override {}
+  void visit (AST::TraitImpl &impl) override;
   void visit (AST::ExternalTypeItem &item) override {}
   void visit (AST::ExternalStaticItem &item) override {}
   void visit (AST::ExternalFunctionItem &item) override {}
@@ -187,6 +187,20 @@ public:
   void visit (AST::SliceType &type) override {}
   void visit (AST::InferredType &type) override {}
   void visit (AST::BareFunctionType &type) override {}
+
+private:
+  enum class Context
+  {
+    INHERENT_IMPL,
+    TRAIT_IMPL,
+    CRATE,
+  };
+
+  std::vector<Context> context;
+
+  void push_context (Context ctx) { context.push_back (ctx); }
+
+  void pop_context () { context.pop_back (); }
 };
 
 } // namespace Rust

Reply via email to