https://gcc.gnu.org/g:011d38a8773cacbd8abb2bdf28247bb3814f9c68

commit r16-4869-g011d38a8773cacbd8abb2bdf28247bb3814f9c68
Author: Philip Herron <[email protected]>
Date:   Mon Sep 22 11:09:56 2025 +0100

    gccrs: Add error diag for self params on plain functions
    
    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 <[email protected]>

Diff:
---
 gcc/rust/hir/rust-ast-lower-item.cc      | 32 ++++++++++++++++++++++++++++++--
 gcc/testsuite/rust/compile/issue-3592.rs |  7 +++++++
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-item.cc 
b/gcc/rust/hir/rust-ast-lower-item.cc
index c6ff50721965..81815ff22eab 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -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
index 000000000000..34018d142187
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3592.rs
@@ -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();
+    }
+}

Reply via email to