]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: privacy: Refactor proc macro privacy check
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Thu, 20 Jul 2023 11:40:35 +0000 (13:40 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:56:01 +0000 (18:56 +0100)
Refactor proc macro specific privacy check in multiple shorter
functions.

gcc/rust/ChangeLog:

* checks/errors/privacy/rust-privacy-reporter.cc (find_proc_macro_attribute):
Add a new function to find a potential proc macro type
attribute on a given item.
(proc_macro_privacy_check): Move all proc macro privacy check in
their own function to avoid cluttering the usual privacy check.
(PrivacyReporter::go): Add call to newly created proc macro
privacy check function.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc

index be357d159b1468da06dd7e7a853521fa6a5f83c9..fc00dcbbae6d419c63ca5938b778ffdc33fa63b3 100644 (file)
@@ -32,46 +32,59 @@ PrivacyReporter::PrivacyReporter (
     current_module (tl::nullopt)
 {}
 
+// Find a proc_macro, proc_macro_derive or proc_macro_attribute
+// attribute in a vector of attribute
+static tl::optional<std::string>
+find_proc_macro_attribute (const AST::AttrVec &outer_attrs)
+{
+  tl::optional<std::string> result;
+
+  for (auto &a : outer_attrs)
+    {
+      auto &segments = a.get_path ().get_segments ();
+      if (segments.size () != 1)
+       continue;
+      auto name = segments.at (0).get_segment_name ();
+      if (name == "proc_macro" || name == "proc_macro_attribute"
+         || name == "proc_macro_derive")
+       result = {name};
+    }
+
+  return result;
+}
+
+// Common check on crate items when dealing with 'proc-macro' crate type.
+static void
+proc_macro_privacy_check (std::unique_ptr<HIR::Item> &item)
+{
+  if (item->get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM)
+    {
+      auto attribute = find_proc_macro_attribute (item->get_outer_attrs ());
+
+      bool pub_item = static_cast<HIR::VisItem *> (item.get ())
+                       ->get_visibility ()
+                       .is_public ();
+
+      if (pub_item && !attribute.has_value ()) // Public non proc-macro
+       rust_error_at (
+         item->get_locus (),
+         "%<proc-macro%> crate types currently cannot export any "
+         "items other than functions tagged with %<#[proc_macro]%>, "
+         "%<#[proc_macro_derive]%> or %<#[proc_macro_attribute]%>");
+      else if (!pub_item && attribute.has_value ()) // Private proc-macro
+       rust_error_at (item->get_locus (),
+                      "functions tagged with %<#[%s]%> must be %<pub%>",
+                      attribute.value ().c_str ());
+    }
+}
+
 void
 PrivacyReporter::go (HIR::Crate &crate)
 {
   for (auto &item : crate.get_items ())
     {
       if (Session::get_instance ().options.is_proc_macro ())
-       {
-         if (item->get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM)
-           {
-             auto &outer_attrs = item->get_outer_attrs ();
-             // Find a proc_macro, proc_macro_derive or proc_macro_attribute
-             // attribute
-             tl::optional<std::string> proc_macro_attribute;
-             for (auto &a : outer_attrs)
-               {
-                 auto &segments = a.get_path ().get_segments ();
-                 if (segments.size () != 1)
-                   break;
-                 auto name = segments.at (0).get_segment_name ();
-                 if (name == "proc_macro" || name == "proc_macro_attribute"
-                     || name == "proc_macro_derive")
-                   proc_macro_attribute = {name};
-               }
-
-             auto vis_item = static_cast<HIR::VisItem *> (item.get ());
-             if (vis_item->get_visibility ().is_public ()
-                 && !proc_macro_attribute.has_value ())
-               rust_error_at (
-                 item->get_locus (),
-                 "%<proc-macro%> crate types currently cannot export any "
-                 "items other than functions tagged with %<#[proc_macro]%>, "
-                 "%<#[proc_macro_derive]%> or %<#[proc_macro_attribute]%>");
-             else if (!vis_item->get_visibility ().is_public ()
-                      && proc_macro_attribute.has_value ())
-               rust_error_at (
-                 item->get_locus (),
-                 "functions tagged with %<#[%s]%> must be %<pub%>",
-                 proc_macro_attribute.value ().c_str ());
-           }
-       }
+       proc_macro_privacy_check (item);
       item->accept_vis (*this);
     }
 }