patch 9.2.0507: Vim9 class: public/protected member name clash uses same error

Commit: 
https://github.com/vim/vim/commit/06a2c7105c3d678cd0c04b934d26810af15b7470
Author: Hirohito Higashi <[email protected]>
Date:   Thu May 21 19:45:59 2026 +0000

    patch 9.2.0507: Vim9 class: public/protected member name clash uses same 
error
    
    Problem:  When a public member and a protected member in a Vim9
              class have the same name (differing only in the leading '_'),
              Vim reports E1369 "Duplicate variable", which is also used for
              plain duplicate definitions.  Users cannot tell from the
              message whether the conflict is the public/protected naming
              rule or a real duplicate.
    Solution: Add a dedicated error E1406 "Public and protected member
              have the same name" and emit it only when the name clash is
              between a public and a protected member.  Keep E1369 for
              genuine duplicate variable definitions (Hirohito Higashi).
    
    fixes:  #20240
    closes: #20277
    
    Signed-off-by: Hirohito Higashi <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/runtime/doc/tags b/runtime/doc/tags
index 6cac191f3..7a4c09031 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -4650,6 +4650,7 @@ E140      message.txt     /*E140*
 E1403  vim9class.txt   /*E1403*
 E1404  vim9class.txt   /*E1404*
 E1405  vim9class.txt   /*E1405*
+E1406  vim9class.txt   /*E1406*
 E1407  vim9class.txt   /*E1407*
 E1408  vim9class.txt   /*E1408*
 E1409  vim9class.txt   /*E1409*
diff --git a/runtime/doc/vim9class.txt b/runtime/doc/vim9class.txt
index 7c92c455c..58458b627 100644
--- a/runtime/doc/vim9class.txt
+++ b/runtime/doc/vim9class.txt
@@ -635,7 +635,7 @@ once.  They can appear in any order, although this order is 
recommended: >
 <
 The "specifies" feature is currently not implemented.
 
-                                                       *E1355* *E1369*
+                                               *E1355* *E1369* *E1406*
 Each variable and method name can be used only once.  It is not possible to
 define a method with the same name and different type of arguments.  It is not
 possible to use a public and protected member variable with the same name.  An
diff --git a/src/errors.h b/src/errors.h
index 3ba7eca8f..4e261c923 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -3564,7 +3564,8 @@ EXTERN char e_abstract_cannot_be_used_in_interface[]
        INIT(= N_("E1404: Abstract cannot be used in an interface"));
 EXTERN char e_using_class_as_value_str[]
        INIT(= N_("E1405: Class \"%s\" cannot be used as a value"));
-// E1406 unused
+EXTERN char e_public_and_protected_member_have_same_name_str_str[]
+       INIT(= N_("E1406: Public and protected member have the same name: %s 
and _%s"));
 EXTERN char e_using_typealias_as_var_val[]
        INIT(= N_("E1407: Cannot use a Typealias as a variable or value"));
 EXTERN char e_final_variable_not_supported_in_interface[]
diff --git a/src/po/vim.pot b/src/po/vim.pot
index e5cf8c102..ad805b30b 100644
--- a/src/po/vim.pot
+++ b/src/po/vim.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Vim
"
 "Report-Msgid-Bugs-To: [email protected]
"
-"POT-Creation-Date: 2026-05-20 18:41+0000
"
+"POT-Creation-Date: 2026-05-21 19:38+0000
"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>
"
 "Language-Team: LANGUAGE <[email protected]>
"
@@ -8488,6 +8488,10 @@ msgstr ""
 msgid "E1405: Class \"%s\" cannot be used as a value"
 msgstr ""
 
+#, c-format
+msgid "E1406: Public and protected member have the same name: %s and _%s"
+msgstr ""
+
 msgid "E1407: Cannot use a Typealias as a variable or value"
 msgstr ""
 
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index 5db6c65d1..35b87b208 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -5143,7 +5143,7 @@ def Test_dup_member_variable()
       var _val = 20
     endclass
   END
-  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
+  v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the 
same name: val and _val', 4)
 
   # Duplicate public and protected member variable
   lines =<< trim END
@@ -5153,7 +5153,7 @@ def Test_dup_member_variable()
       public var val = 10
     endclass
   END
-  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
+  v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the 
same name: val and _val', 4)
 
   # Duplicate class member variable
   lines =<< trim END
@@ -5163,7 +5163,7 @@ def Test_dup_member_variable()
       static var _s: string = "def"
     endclass
   END
-  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
+  v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the 
same name: s and _s', 4)
 
   # Duplicate public and protected class member variable
   lines =<< trim END
@@ -5173,7 +5173,7 @@ def Test_dup_member_variable()
       static var _s: string = "def"
     endclass
   END
-  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
+  v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the 
same name: s and _s', 4)
 
   # Duplicate class and object member variable
   lines =<< trim END
@@ -5230,7 +5230,7 @@ def Test_dup_member_variable()
       var _val = 20
     endclass
   END
-  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
+  v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the 
same name: val and _val', 9)
 
   # Duplicate object member variable in a derived class
   lines =<< trim END
@@ -5244,7 +5244,7 @@ def Test_dup_member_variable()
       var val = 20
     endclass
   END
-  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
+  v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the 
same name: val and _val', 9)
 
   # Two member variables with a common prefix
   lines =<< trim END
diff --git a/src/version.c b/src/version.c
index dc31e54a7..863043dab 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    507,
 /**/
     506,
 /**/
diff --git a/src/vim9class.c b/src/vim9class.c
index 8edd022bd..bc10ce8b0 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -461,13 +461,14 @@ extends_check_dup_members(
     {
        class_T     *p_cl = extends_cl;
        ocmember_T  *c_m = members + c_i;
-       char_u      *pstr = (*c_m->ocm_name.string == '_')
-                                   ? c_m->ocm_name.string + 1 : 
c_m->ocm_name.string;
+       bool        c_protected = (*c_m->ocm_name.string == '_');
+       char_u      *pstr = c_m->ocm_name.string + c_protected;
 
        // Check in all the parent classes in the lineage
        while (p_cl != NULL)
        {
            int p_member_count = p_cl->class_obj_member_count;
+
            if (p_member_count == 0)
            {
                p_cl = p_cl->class_extends;
@@ -478,12 +479,17 @@ extends_check_dup_members(
            // Compare against all the members in the parent class
            for (int p_i = 0; p_i < p_member_count; p_i++)
            {
-               ocmember_T      *p_m = p_members + p_i;
-               char_u  *qstr = (*p_m->ocm_name.string == '_')
-                   ? p_m->ocm_name.string + 1 : p_m->ocm_name.string;
+               ocmember_T  *p_m = p_members + p_i;
+               bool        p_protected = (*p_m->ocm_name.string == '_');
+               char_u      *qstr = p_m->ocm_name.string + p_protected;
                if (STRCMP(pstr, qstr) == 0)
                {
-                   semsg(_(e_duplicate_variable_str), c_m->ocm_name.string);
+                   if (c_protected != p_protected)
+                       
semsg(_(e_public_and_protected_member_have_same_name_str_str),
+                               pstr, pstr);
+                   else
+                       semsg(_(e_duplicate_variable_str),
+                               c_m->ocm_name.string);
                    return FALSE;
                }
            }
@@ -1040,18 +1046,18 @@ is_duplicate_variable(
     char_u     *varname,
     char_u     *varname_end)
 {
-    string_T   pstr = {varname, (size_t)(varname_end - varname)};  // Note: 
the .string field may
-                                                                   // point to 
a string longer
-                                                                   // than the 
.length field.
-                                                                   // So we 
need to use STRNCMP()
-                                                                   // to 
compare it.
+    // Note: the .string field may point to a string longer than the .length
+    // field.  So we need to use STRNCMP() to compare it.
+    string_T   pstr = {varname, (size_t)(varname_end - varname)};
     int                dup = FALSE;
+    bool       p_protected = false;
 
     // Step over a leading '_'.
     if (*pstr.string == '_')
     {
        pstr.string++;
        pstr.length--;
+       p_protected = true;
     }
 
     // loop == 1: class variables, loop == 2: object variables
@@ -1062,12 +1068,14 @@ is_duplicate_variable(
        {
            ocmember_T *m = ((ocmember_T *)vgap->ga_data) + i;
            string_T    qstr = {m->ocm_name.string, m->ocm_name.length};
+           bool        q_protected = false;
 
            // Step over a leading '_'.
            if (*qstr.string == '_')
            {
                qstr.string++;
                qstr.length--;
+               q_protected = true;
            }
 
            if (pstr.length == qstr.length
@@ -1076,7 +1084,11 @@ is_duplicate_variable(
                char_u  save_c = *varname_end;
 
                *varname_end = NUL;
-               semsg(_(e_duplicate_variable_str), varname);
+               if (p_protected != q_protected)
+                   
semsg(_(e_public_and_protected_member_have_same_name_str_str),
+                                              pstr.string, pstr.string);
+               else
+                   semsg(_(e_duplicate_variable_str), varname);
                *varname_end = save_c;
                dup = TRUE;
                break;

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1wQ9Yr-00GwLz-ER%40256bit.org.

Raspunde prin e-mail lui