Repository: sphinx-doc/sphinx

Issue:
glossary: Wrong hyperlinks are generated for non alphanum terms
**Describe the bug**
glossary: Wrong hyperlinks are generated for non alphanum terms

**To Reproduce**
With following input, `:term:` role generates wrong hyperlink to "1" entry, not "/".

```
Welcome to test's documentation!
================================

:term:`/`

.. glossary::

   1
       description

   /
       description
```

**Expected behavior**
It generates a hyperlink to "/" correctly.

**Your project**
None

**Screenshots**
None

**Environment info**
- OS: Mac
- Python version: 3.7.3
- Sphinx version: 2.2.0+
- Sphinx extensions: None
- Extra tools: None

**Additional context**
None

Discussion:

Patch:
diff --git a/CHANGES b/CHANGES
index 883980a71..b8e612635 100644
--- a/CHANGES
+++ b/CHANGES
@@ -55,6 +55,7 @@ Bugs fixed
   each comma separated option
 * #6549: sphinx-build: Escaped characters in error messages
 * #6545: doctest comments not getting trimmed since Sphinx 1.8.0
+* #6561: glossary: Wrong hyperlinks are generated for non alphanumeric terms
 
 Testing
 --------
diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py
index 66171646a..6b4820500 100644
--- a/sphinx/domains/std.py
+++ b/sphinx/domains/std.py
@@ -255,9 +255,9 @@ def make_glossary_term(env: "BuildEnvironment", textnodes: Iterable[Node], index
         new_id = nodes.make_id('term-' + termtext)
         if new_id == 'term':
             # the term is not good for node_id.  Generate it by sequence number instead.
-            new_id = 'term-' + str(len(gloss_entries))
-    if new_id in gloss_entries:
-        new_id = 'term-' + str(len(gloss_entries))
+            new_id = 'term-%d' % env.new_serialno('glossary')
+    while new_id in gloss_entries:
+        new_id = 'term-%d' % env.new_serialno('glossary')
     gloss_entries.add(new_id)
 
     std = cast(StandardDomain, env.get_domain('std'))


Test patch:
diff --git a/tests/test_domain_std.py b/tests/test_domain_std.py
index 1a03060e6..c7a7b496a 100644
--- a/tests/test_domain_std.py
+++ b/tests/test_domain_std.py
@@ -244,6 +244,17 @@ def test_glossary_sorted(app):
                 [nodes.definition, nodes.paragraph, "description"])
 
 
+def test_glossary_alphanumeric(app):
+    text = (".. glossary::\n"
+            "\n"
+            "   1\n"
+            "   /\n")
+    restructuredtext.parse(app, text)
+    objects = list(app.env.get_domain("std").get_objects())
+    assert ("1", "1", "term", "index", "term-1", -1) in objects
+    assert ("/", "/", "term", "index", "term-0", -1) in objects
+
+
 def test_cmdoption(app):
     text = (".. program:: ls\n"
             "\n"
diff --git a/tests/test_environment_indexentries.py b/tests/test_environment_indexentries.py
index 4083eae04..5c0ab7849 100644
--- a/tests/test_environment_indexentries.py
+++ b/tests/test_environment_indexentries.py
@@ -131,4 +131,4 @@ def test_create_index_by_key(app):
     assert len(index) == 3
     assert index[0] == ('D', [('docutils', [[('main', '#term-docutils')], [], None])])
     assert index[1] == ('P', [('Python', [[('main', '#term-python')], [], None])])
-    assert index[2] == ('ス', [('スフィンクス', [[('main', '#term-2')], [], 'ス'])])
+    assert index[2] == ('ス', [('スフィンクス', [[('main', '#term-0')], [], 'ス'])])