Subject: bug#62761: ruby-add-log-current-method drops some segments when singleton definition references outer module

From: Dmitry Gutov <[email-masked]>
Date: Tue, 11 Apr 2023 00:02:03 +0300

Example:

   module M
     module N
       module C
         class D
           def C.foo
             _
           end
         end
       end
     end
   end

(ruby-add-log-current-method) currently returns "M::C.foo"

While it should return "M::N::C.foo". Patch attached.

This discovery stems from Mattias Engdegård's report (in private) about 
an ignored return value from `nreverse`.

Is this good for emacs-29?

It seems pretty safe (with decent test coverage, including the new 
test), but probably low urgency. Not a regression either.

diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index beccb8182a7..1199af64821 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -1911,7 +1911,7 @@ ruby-add-log-current-method
                         (while ml
                           (if (string-equal (car ml) (car mn))
                               (setq mlist (nreverse (cdr ml)) ml nil))
-                          (or (setq ml (cdr ml)) (nreverse mlist))))
+                          (setq ml (cdr ml))))
                       (if mlist
                           (setcdr (last mlist) (butlast mn))
                         (setq mlist (butlast mn))))
diff --git a/test/lisp/progmodes/ruby-mode-tests.el b/test/lisp/progmodes/ruby-mode-tests.el
index 8a75c83d2c3..117385ea3e8 100644
--- a/test/lisp/progmodes/ruby-mode-tests.el
+++ b/test/lisp/progmodes/ruby-mode-tests.el
@@ -567,6 +567,22 @@ ruby-add-log-current-method-namespace-shorthand
     (search-backward "_")
     (should (string= (ruby-add-log-current-method) "C::D#foo"))))
 
+(ert-deftest ruby-add-log-current-method-singleton-referencing-outer ()
+  (ruby-with-temp-buffer (ruby-test-string
+                          "module M
+                          |  module N
+                          |    module C
+                          |      class D
+                          |        def C.foo
+                          |          _
+                          |        end
+                          |      end
+                          |    end
+                          |  end
+                          |end")
+    (search-backward "_")
+    (should (string= (ruby-add-log-current-method) "M::N::C.foo"))))
+
 (ert-deftest ruby-add-log-current-method-after-inner-class ()
   (ruby-with-temp-buffer (ruby-test-string
                           "module M