]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Add error diag for self params on plain functions
authorPhilip Herron <herron.philip@googlemail.com>
Mon, 22 Sep 2025 10:09:56 +0000 (11:09 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Thu, 30 Oct 2025 20:30:52 +0000 (21:30 +0100)
self params dont have a type unless used within impl blocks. Rustc as far as I
can tell in this senario generics a synthetic param of type Self in this senario
so that it keeps consistent error diagnostic for number of parameters but the
logic for what the parameter typpe should be seems unclear.

Fixes Rust-GCC#3592

gcc/rust/ChangeLog:

* hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): add error diagnostic

gcc/testsuite/ChangeLog:

* rust/compile/issue-3592.rs: New test.

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
gcc/rust/hir/rust-ast-lower-item.cc
gcc/testsuite/rust/compile/issue-3592.rs [new file with mode: 0644]

index c6ff50721965458d54bc21545144449bd032f77a..81815ff22eab737adb7d6b131b10c86a44dc363e 100644 (file)
@@ -418,10 +418,39 @@ ASTLoweringItem::visit (AST::Function &function)
   std::vector<HIR::FunctionParam> function_params;
   function_params.reserve (function.get_function_params ().size ());
 
+  auto crate_num = mappings.get_current_crate ();
   for (auto &p : function.get_function_params ())
     {
-      if (p->is_variadic () || p->is_self ())
+      if (p->is_variadic ())
        continue;
+      if (p->is_self ())
+       {
+         rich_location r (line_table, p->get_locus ());
+         r.add_range (function.get_locus ());
+         rust_error_at (
+           r, "%<self%> parameter is only allowed in associated functions");
+
+         // rustc creates a synthetic regular fn-param here pointing to a
+         // generic Self as far as i can see but that seems over the top for
+         // now.
+         //
+         // see this example (invalid code):
+         //
+         // pub trait X {
+         //   fn x() {
+         //     fn f(&mut self) {}
+         //     f();
+         //   }
+         // }
+         //
+         // without a synthetic param we wont get the number of args error as
+         // well but i think this is fine for now.
+         //
+         // problem is what we make the param type to become...
+
+         continue;
+       }
+
       auto param = static_cast<AST::FunctionParam &> (*p);
 
       auto translated_pattern = std::unique_ptr<HIR::Pattern> (
@@ -445,7 +474,6 @@ ASTLoweringItem::visit (AST::Function &function)
       ASTLoweringBlock::translate (*function.get_definition ().value (),
                                   &terminated));
 
-  auto crate_num = mappings.get_current_crate ();
   Analysis::NodeMapping mapping (crate_num, function.get_node_id (),
                                 mappings.get_next_hir_id (crate_num),
                                 mappings.get_next_localdef_id (crate_num));
diff --git a/gcc/testsuite/rust/compile/issue-3592.rs b/gcc/testsuite/rust/compile/issue-3592.rs
new file mode 100644 (file)
index 0000000..34018d1
--- /dev/null
@@ -0,0 +1,7 @@
+pub trait X {
+    fn x() {
+        fn f(&mut self) {}
+        // { dg-error ".self. parameter is only allowed in associated functions" "" { target *-*-* } .-1 }
+        f();
+    }
+}