make hashes always the size of pointers; introduce Py_hash_t #9778
diff --git a/Include/bytesobject.h b/Include/bytesobject.h
index 916e3f7..3c69d25 100644
--- a/Include/bytesobject.h
+++ b/Include/bytesobject.h
@@ -29,7 +29,7 @@
 
 typedef struct {
     PyObject_VAR_HEAD
-    long ob_shash;
+    Py_hash_t ob_shash;
     char ob_sval[1];
 
     /* Invariants:
diff --git a/Include/datetime.h b/Include/datetime.h
index f472c42..2d71fce 100644
--- a/Include/datetime.h
+++ b/Include/datetime.h
@@ -34,7 +34,7 @@
 typedef struct
 {
     PyObject_HEAD
-    long hashcode;              /* -1 when unknown */
+    Py_hash_t hashcode;         /* -1 when unknown */
     int days;                   /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */
     int seconds;                /* 0 <= seconds < 24*3600 is invariant */
     int microseconds;           /* 0 <= microseconds < 1000000 is invariant */
@@ -51,7 +51,7 @@
  */
 #define _PyTZINFO_HEAD          \
     PyObject_HEAD               \
-    long hashcode;              \
+    Py_hash_t hashcode;         \
     char hastzinfo;             /* boolean flag */
 
 /* No _PyDateTime_BaseTZInfo is allocated; it's just to have something
diff --git a/Include/dictobject.h b/Include/dictobject.h
index 2481921..024a688 100644
--- a/Include/dictobject.h
+++ b/Include/dictobject.h
@@ -48,11 +48,8 @@
 #define PyDict_MINSIZE 8
 
 typedef struct {
-    /* Cached hash code of me_key.  Note that hash codes are C longs.
-     * We have to use Py_ssize_t instead because dict_popitem() abuses
-     * me_hash to hold a search finger.
-     */
-    Py_ssize_t me_hash;
+    /* Cached hash code of me_key. */
+    Py_hash_t me_hash;
     PyObject *me_key;
     PyObject *me_value;
 } PyDictEntry;
@@ -84,7 +81,7 @@
      * setitem calls.
      */
     PyDictEntry *ma_table;
-    PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash);
+    PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, Py_hash_t hash);
     PyDictEntry ma_smalltable[PyDict_MINSIZE];
 };
 
@@ -116,14 +113,14 @@
 PyAPI_FUNC(int) PyDict_Next(
     PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value);
 PyAPI_FUNC(int) _PyDict_Next(
-    PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, long *hash);
+    PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash);
 PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp);
 PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp);
 PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp);
 PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp);
 PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp);
 PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key);
-PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, long hash);
+PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash);
 PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
 PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
 PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);
diff --git a/Include/object.h b/Include/object.h
index ef73a21..f14fd07 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -275,7 +275,7 @@
 typedef int (*setattrfunc)(PyObject *, char *, PyObject *);
 typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *);
 typedef PyObject *(*reprfunc)(PyObject *);
-typedef long (*hashfunc)(PyObject *);
+typedef Py_hash_t (*hashfunc)(PyObject *);
 typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
 typedef PyObject *(*getiterfunc) (PyObject *);
 typedef PyObject *(*iternextfunc) (PyObject *);
@@ -440,8 +440,8 @@
 PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *);
 PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *,
                                               PyObject *, PyObject *);
-PyAPI_FUNC(long) PyObject_Hash(PyObject *);
-PyAPI_FUNC(long) PyObject_HashNotImplemented(PyObject *);
+PyAPI_FUNC(Py_hash_t) PyObject_Hash(PyObject *);
+PyAPI_FUNC(Py_hash_t) PyObject_HashNotImplemented(PyObject *);
 PyAPI_FUNC(int) PyObject_IsTrue(PyObject *);
 PyAPI_FUNC(int) PyObject_Not(PyObject *);
 PyAPI_FUNC(int) PyCallable_Check(PyObject *);
@@ -470,8 +470,8 @@
 PyAPI_FUNC(void) Py_ReprLeave(PyObject *);
 
 /* Helpers for hash functions */
-PyAPI_FUNC(long) _Py_HashDouble(double);
-PyAPI_FUNC(long) _Py_HashPointer(void*);
+PyAPI_FUNC(Py_hash_t) _Py_HashDouble(double);
+PyAPI_FUNC(Py_hash_t) _Py_HashPointer(void*);
 
 /* Helper for passing objects to printf and the like */
 #define PyObject_REPR(obj) _PyUnicode_AsString(PyObject_Repr(obj))
diff --git a/Include/pyport.h b/Include/pyport.h
index 5e98f0b..4331bf9 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -130,7 +130,7 @@
    _PyHash_Double in Objects/object.c.  Numeric hashes are based on
    reduction modulo the prime 2**_PyHASH_BITS - 1. */
 
-#if SIZEOF_LONG >= 8
+#if SIZEOF_VOID_P >= 8
 #define _PyHASH_BITS 61
 #else
 #define _PyHASH_BITS 31
@@ -177,6 +177,9 @@
 #   error "Python needs a typedef for Py_ssize_t in pyport.h."
 #endif
 
+/* Py_hash_t is the same size as a pointer. */
+typedef Py_ssize_t Py_hash_t;
+
 /* Largest possible value of size_t.
    SIZE_MAX is part of C99, so it might be defined on some
    platforms. If it is not defined, (size_t)-1 is a portable
diff --git a/Include/setobject.h b/Include/setobject.h
index 574caf7..023c5fa 100644
--- a/Include/setobject.h
+++ b/Include/setobject.h
@@ -22,11 +22,8 @@
 #define PySet_MINSIZE 8
 
 typedef struct {
-    /* Cached hash code of the key.  Note that hash codes are C longs.
-     * We have to use Py_ssize_t instead because set_pop() abuses
-     * the hash field to hold a search finger.
-     */
-    Py_ssize_t hash;
+    /* Cached hash code of the key. */
+    Py_hash_t hash;
     PyObject *key;
 } setentry;
 
@@ -53,10 +50,10 @@
      * saves repeated runtime null-tests.
      */
     setentry *table;
-    setentry *(*lookup)(PySetObject *so, PyObject *key, long hash);
+    setentry *(*lookup)(PySetObject *so, PyObject *key, Py_hash_t hash);
     setentry smalltable[PySet_MINSIZE];
 
-    long hash;                  /* only used by frozenset objects */
+    Py_hash_t hash;                  /* only used by frozenset objects */
     PyObject *weakreflist;      /* List of weak references */
 };
 
@@ -93,7 +90,7 @@
 PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key);
 PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key);
 PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key);
-PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash);
+PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash);
 PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set);
 PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable);
 
diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h
index f61712b..42da8c3 100644
--- a/Include/unicodeobject.h
+++ b/Include/unicodeobject.h
@@ -372,7 +372,7 @@
     PyObject_HEAD
     Py_ssize_t length;          /* Length of raw Unicode data in buffer */
     Py_UNICODE *str;            /* Raw Unicode buffer */
-    long hash;                  /* Hash value; -1 if not set */
+    Py_hash_t hash;             /* Hash value; -1 if not set */
     int state;                  /* != 0 if interned. In this case the two
                                  * references from the dictionary to this object
                                  * are *not* counted in ob_refcnt. */
diff --git a/Include/weakrefobject.h b/Include/weakrefobject.h
index f15c9d9c..b201d08 100644
--- a/Include/weakrefobject.h
+++ b/Include/weakrefobject.h
@@ -27,7 +27,7 @@
     /* A cache for wr_object's hash code.  As usual for hashes, this is -1
      * if the hash code isn't known yet.
      */
-    long hash;
+    Py_hash_t hash;
 
     /* If wr_object is weakly referenced, wr_object has a doubly-linked NULL-
      * terminated list of weak references to it.  These are the list pointers.