bpo-34822: Simplify AST for subscription. (GH-9605)

* Remove the slice type.
* Make Slice a kind of the expr type instead of the slice type.
* Replace ExtSlice(slices) with Tuple(slices, Load()).
* Replace Index(value) with a value itself.

All non-terminal nodes in AST for expressions are now of the expr type.
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 47c88b6..f58dd9c 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -52,7 +52,6 @@
     PyObject *ExceptHandler_type;
     PyObject *Expr_type;
     PyObject *Expression_type;
-    PyObject *ExtSlice_type;
     PyObject *FloorDiv_singleton;
     PyObject *FloorDiv_type;
     PyObject *For_type;
@@ -71,7 +70,6 @@
     PyObject *Import_type;
     PyObject *In_singleton;
     PyObject *In_type;
-    PyObject *Index_type;
     PyObject *Interactive_type;
     PyObject *Invert_singleton;
     PyObject *Invert_type;
@@ -166,7 +164,6 @@
     PyObject *ctx;
     PyObject *decorator_list;
     PyObject *defaults;
-    PyObject *dims;
     PyObject *elt;
     PyObject *elts;
     PyObject *end_col_offset;
@@ -213,7 +210,6 @@
     PyObject *right;
     PyObject *simple;
     PyObject *slice;
-    PyObject *slice_type;
     PyObject *step;
     PyObject *stmt_type;
     PyObject *tag;
@@ -281,7 +277,6 @@
     Py_CLEAR(astmodulestate(module)->ExceptHandler_type);
     Py_CLEAR(astmodulestate(module)->Expr_type);
     Py_CLEAR(astmodulestate(module)->Expression_type);
-    Py_CLEAR(astmodulestate(module)->ExtSlice_type);
     Py_CLEAR(astmodulestate(module)->FloorDiv_singleton);
     Py_CLEAR(astmodulestate(module)->FloorDiv_type);
     Py_CLEAR(astmodulestate(module)->For_type);
@@ -300,7 +295,6 @@
     Py_CLEAR(astmodulestate(module)->Import_type);
     Py_CLEAR(astmodulestate(module)->In_singleton);
     Py_CLEAR(astmodulestate(module)->In_type);
-    Py_CLEAR(astmodulestate(module)->Index_type);
     Py_CLEAR(astmodulestate(module)->Interactive_type);
     Py_CLEAR(astmodulestate(module)->Invert_singleton);
     Py_CLEAR(astmodulestate(module)->Invert_type);
@@ -395,7 +389,6 @@
     Py_CLEAR(astmodulestate(module)->ctx);
     Py_CLEAR(astmodulestate(module)->decorator_list);
     Py_CLEAR(astmodulestate(module)->defaults);
-    Py_CLEAR(astmodulestate(module)->dims);
     Py_CLEAR(astmodulestate(module)->elt);
     Py_CLEAR(astmodulestate(module)->elts);
     Py_CLEAR(astmodulestate(module)->end_col_offset);
@@ -442,7 +435,6 @@
     Py_CLEAR(astmodulestate(module)->right);
     Py_CLEAR(astmodulestate(module)->simple);
     Py_CLEAR(astmodulestate(module)->slice);
-    Py_CLEAR(astmodulestate(module)->slice_type);
     Py_CLEAR(astmodulestate(module)->step);
     Py_CLEAR(astmodulestate(module)->stmt_type);
     Py_CLEAR(astmodulestate(module)->tag);
@@ -509,7 +501,6 @@
     Py_VISIT(astmodulestate(module)->ExceptHandler_type);
     Py_VISIT(astmodulestate(module)->Expr_type);
     Py_VISIT(astmodulestate(module)->Expression_type);
-    Py_VISIT(astmodulestate(module)->ExtSlice_type);
     Py_VISIT(astmodulestate(module)->FloorDiv_singleton);
     Py_VISIT(astmodulestate(module)->FloorDiv_type);
     Py_VISIT(astmodulestate(module)->For_type);
@@ -528,7 +519,6 @@
     Py_VISIT(astmodulestate(module)->Import_type);
     Py_VISIT(astmodulestate(module)->In_singleton);
     Py_VISIT(astmodulestate(module)->In_type);
-    Py_VISIT(astmodulestate(module)->Index_type);
     Py_VISIT(astmodulestate(module)->Interactive_type);
     Py_VISIT(astmodulestate(module)->Invert_singleton);
     Py_VISIT(astmodulestate(module)->Invert_type);
@@ -623,7 +613,6 @@
     Py_VISIT(astmodulestate(module)->ctx);
     Py_VISIT(astmodulestate(module)->decorator_list);
     Py_VISIT(astmodulestate(module)->defaults);
-    Py_VISIT(astmodulestate(module)->dims);
     Py_VISIT(astmodulestate(module)->elt);
     Py_VISIT(astmodulestate(module)->elts);
     Py_VISIT(astmodulestate(module)->end_col_offset);
@@ -670,7 +659,6 @@
     Py_VISIT(astmodulestate(module)->right);
     Py_VISIT(astmodulestate(module)->simple);
     Py_VISIT(astmodulestate(module)->slice);
-    Py_VISIT(astmodulestate(module)->slice_type);
     Py_VISIT(astmodulestate(module)->step);
     Py_VISIT(astmodulestate(module)->stmt_type);
     Py_VISIT(astmodulestate(module)->tag);
@@ -733,7 +721,6 @@
     if ((state->ctx = PyUnicode_InternFromString("ctx")) == NULL) return 0;
     if ((state->decorator_list = PyUnicode_InternFromString("decorator_list")) == NULL) return 0;
     if ((state->defaults = PyUnicode_InternFromString("defaults")) == NULL) return 0;
-    if ((state->dims = PyUnicode_InternFromString("dims")) == NULL) return 0;
     if ((state->elt = PyUnicode_InternFromString("elt")) == NULL) return 0;
     if ((state->elts = PyUnicode_InternFromString("elts")) == NULL) return 0;
     if ((state->end_col_offset = PyUnicode_InternFromString("end_col_offset")) == NULL) return 0;
@@ -1035,19 +1022,12 @@
     "elts",
     "ctx",
 };
-static PyObject* ast2obj_expr_context(expr_context_ty);
-static PyObject* ast2obj_slice(void*);
 static const char * const Slice_fields[]={
     "lower",
     "upper",
     "step",
 };
-static const char * const ExtSlice_fields[]={
-    "dims",
-};
-static const char * const Index_fields[]={
-    "value",
-};
+static PyObject* ast2obj_expr_context(expr_context_ty);
 static PyObject* ast2obj_boolop(boolop_ty);
 static PyObject* ast2obj_operator(operator_ty);
 static PyObject* ast2obj_unaryop(unaryop_ty);
@@ -1635,6 +1615,14 @@
     if (!state->List_type) return 0;
     state->Tuple_type = make_type("Tuple", state->expr_type, Tuple_fields, 2);
     if (!state->Tuple_type) return 0;
+    state->Slice_type = make_type("Slice", state->expr_type, Slice_fields, 3);
+    if (!state->Slice_type) return 0;
+    if (PyObject_SetAttr(state->Slice_type, state->lower, Py_None) == -1)
+        return 0;
+    if (PyObject_SetAttr(state->Slice_type, state->upper, Py_None) == -1)
+        return 0;
+    if (PyObject_SetAttr(state->Slice_type, state->step, Py_None) == -1)
+        return 0;
     state->expr_context_type = make_type("expr_context", state->AST_type, NULL,
                                          0);
     if (!state->expr_context_type) return 0;
@@ -1673,22 +1661,6 @@
     state->Param_singleton = PyType_GenericNew((PyTypeObject
                                                *)state->Param_type, NULL, NULL);
     if (!state->Param_singleton) return 0;
-    state->slice_type = make_type("slice", state->AST_type, NULL, 0);
-    if (!state->slice_type) return 0;
-    if (!add_attributes(state->slice_type, NULL, 0)) return 0;
-    state->Slice_type = make_type("Slice", state->slice_type, Slice_fields, 3);
-    if (!state->Slice_type) return 0;
-    if (PyObject_SetAttr(state->Slice_type, state->lower, Py_None) == -1)
-        return 0;
-    if (PyObject_SetAttr(state->Slice_type, state->upper, Py_None) == -1)
-        return 0;
-    if (PyObject_SetAttr(state->Slice_type, state->step, Py_None) == -1)
-        return 0;
-    state->ExtSlice_type = make_type("ExtSlice", state->slice_type,
-                                     ExtSlice_fields, 1);
-    if (!state->ExtSlice_type) return 0;
-    state->Index_type = make_type("Index", state->slice_type, Index_fields, 1);
-    if (!state->Index_type) return 0;
     state->boolop_type = make_type("boolop", state->AST_type, NULL, 0);
     if (!state->boolop_type) return 0;
     if (!add_attributes(state->boolop_type, NULL, 0)) return 0;
@@ -1929,7 +1901,6 @@
 static int obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena);
 static int obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena*
                                 arena);
-static int obj2ast_slice(PyObject* obj, slice_ty* out, PyArena* arena);
 static int obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena);
 static int obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena);
 static int obj2ast_unaryop(PyObject* obj, unaryop_ty* out, PyArena* arena);
@@ -3092,7 +3063,7 @@
 }
 
 expr_ty
-Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int lineno, int
+Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int lineno, int
           col_offset, int end_lineno, int end_col_offset, PyArena *arena)
 {
     expr_ty p;
@@ -3227,46 +3198,22 @@
     return p;
 }
 
-slice_ty
-Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena)
+expr_ty
+Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int col_offset,
+      int end_lineno, int end_col_offset, PyArena *arena)
 {
-    slice_ty p;
-    p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
+    expr_ty p;
+    p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
     if (!p)
         return NULL;
     p->kind = Slice_kind;
     p->v.Slice.lower = lower;
     p->v.Slice.upper = upper;
     p->v.Slice.step = step;
-    return p;
-}
-
-slice_ty
-ExtSlice(asdl_seq * dims, PyArena *arena)
-{
-    slice_ty p;
-    p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
-    if (!p)
-        return NULL;
-    p->kind = ExtSlice_kind;
-    p->v.ExtSlice.dims = dims;
-    return p;
-}
-
-slice_ty
-Index(expr_ty value, PyArena *arena)
-{
-    slice_ty p;
-    if (!value) {
-        PyErr_SetString(PyExc_ValueError,
-                        "field value is required for Index");
-        return NULL;
-    }
-    p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
-    if (!p)
-        return NULL;
-    p->kind = Index_kind;
-    p->v.Index.value = value;
+    p->lineno = lineno;
+    p->col_offset = col_offset;
+    p->end_lineno = end_lineno;
+    p->end_col_offset = end_col_offset;
     return p;
 }
 
@@ -4389,7 +4336,7 @@
         if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
             goto failed;
         Py_DECREF(value);
-        value = ast2obj_slice(o->v.Subscript.slice);
+        value = ast2obj_expr(o->v.Subscript.slice);
         if (!value) goto failed;
         if (PyObject_SetAttr(result, astmodulestate_global->slice, value) == -1)
             goto failed;
@@ -4460,6 +4407,26 @@
             goto failed;
         Py_DECREF(value);
         break;
+    case Slice_kind:
+        tp = (PyTypeObject *)astmodulestate_global->Slice_type;
+        result = PyType_GenericNew(tp, NULL, NULL);
+        if (!result) goto failed;
+        value = ast2obj_expr(o->v.Slice.lower);
+        if (!value) goto failed;
+        if (PyObject_SetAttr(result, astmodulestate_global->lower, value) == -1)
+            goto failed;
+        Py_DECREF(value);
+        value = ast2obj_expr(o->v.Slice.upper);
+        if (!value) goto failed;
+        if (PyObject_SetAttr(result, astmodulestate_global->upper, value) == -1)
+            goto failed;
+        Py_DECREF(value);
+        value = ast2obj_expr(o->v.Slice.step);
+        if (!value) goto failed;
+        if (PyObject_SetAttr(result, astmodulestate_global->step, value) == -1)
+            goto failed;
+        Py_DECREF(value);
+        break;
     }
     value = ast2obj_int(o->lineno);
     if (!value) goto failed;
@@ -4516,65 +4483,6 @@
             return NULL;
     }
 }
-PyObject*
-ast2obj_slice(void* _o)
-{
-    slice_ty o = (slice_ty)_o;
-    PyObject *result = NULL, *value = NULL;
-    PyTypeObject *tp;
-    if (!o) {
-        Py_RETURN_NONE;
-    }
-
-    switch (o->kind) {
-    case Slice_kind:
-        tp = (PyTypeObject *)astmodulestate_global->Slice_type;
-        result = PyType_GenericNew(tp, NULL, NULL);
-        if (!result) goto failed;
-        value = ast2obj_expr(o->v.Slice.lower);
-        if (!value) goto failed;
-        if (PyObject_SetAttr(result, astmodulestate_global->lower, value) == -1)
-            goto failed;
-        Py_DECREF(value);
-        value = ast2obj_expr(o->v.Slice.upper);
-        if (!value) goto failed;
-        if (PyObject_SetAttr(result, astmodulestate_global->upper, value) == -1)
-            goto failed;
-        Py_DECREF(value);
-        value = ast2obj_expr(o->v.Slice.step);
-        if (!value) goto failed;
-        if (PyObject_SetAttr(result, astmodulestate_global->step, value) == -1)
-            goto failed;
-        Py_DECREF(value);
-        break;
-    case ExtSlice_kind:
-        tp = (PyTypeObject *)astmodulestate_global->ExtSlice_type;
-        result = PyType_GenericNew(tp, NULL, NULL);
-        if (!result) goto failed;
-        value = ast2obj_list(o->v.ExtSlice.dims, ast2obj_slice);
-        if (!value) goto failed;
-        if (PyObject_SetAttr(result, astmodulestate_global->dims, value) == -1)
-            goto failed;
-        Py_DECREF(value);
-        break;
-    case Index_kind:
-        tp = (PyTypeObject *)astmodulestate_global->Index_type;
-        result = PyType_GenericNew(tp, NULL, NULL);
-        if (!result) goto failed;
-        value = ast2obj_expr(o->v.Index.value);
-        if (!value) goto failed;
-        if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
-            goto failed;
-        Py_DECREF(value);
-        break;
-    }
-    return result;
-failed:
-    Py_XDECREF(value);
-    Py_XDECREF(result);
-    return NULL;
-}
-
 PyObject* ast2obj_boolop(boolop_ty o)
 {
     switch(o) {
@@ -8421,7 +8329,7 @@
     }
     if (isinstance) {
         expr_ty value;
-        slice_ty slice;
+        expr_ty slice;
         expr_context_ty ctx;
 
         if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
@@ -8446,7 +8354,7 @@
         }
         else {
             int res;
-            res = obj2ast_slice(tmp, &slice, arena);
+            res = obj2ast_expr(tmp, &slice, arena);
             if (res != 0) goto failed;
             Py_CLEAR(tmp);
         }
@@ -8668,6 +8576,60 @@
         if (*out == NULL) goto failed;
         return 0;
     }
+    tp = astmodulestate_global->Slice_type;
+    isinstance = PyObject_IsInstance(obj, tp);
+    if (isinstance == -1) {
+        return 1;
+    }
+    if (isinstance) {
+        expr_ty lower;
+        expr_ty upper;
+        expr_ty step;
+
+        if (_PyObject_LookupAttr(obj, astmodulestate_global->lower, &tmp) < 0) {
+            return 1;
+        }
+        if (tmp == NULL || tmp == Py_None) {
+            Py_CLEAR(tmp);
+            lower = NULL;
+        }
+        else {
+            int res;
+            res = obj2ast_expr(tmp, &lower, arena);
+            if (res != 0) goto failed;
+            Py_CLEAR(tmp);
+        }
+        if (_PyObject_LookupAttr(obj, astmodulestate_global->upper, &tmp) < 0) {
+            return 1;
+        }
+        if (tmp == NULL || tmp == Py_None) {
+            Py_CLEAR(tmp);
+            upper = NULL;
+        }
+        else {
+            int res;
+            res = obj2ast_expr(tmp, &upper, arena);
+            if (res != 0) goto failed;
+            Py_CLEAR(tmp);
+        }
+        if (_PyObject_LookupAttr(obj, astmodulestate_global->step, &tmp) < 0) {
+            return 1;
+        }
+        if (tmp == NULL || tmp == Py_None) {
+            Py_CLEAR(tmp);
+            step = NULL;
+        }
+        else {
+            int res;
+            res = obj2ast_expr(tmp, &step, arena);
+            if (res != 0) goto failed;
+            Py_CLEAR(tmp);
+        }
+        *out = Slice(lower, upper, step, lineno, col_offset, end_lineno,
+                     end_col_offset, arena);
+        if (*out == NULL) goto failed;
+        return 0;
+    }
 
     PyErr_Format(PyExc_TypeError, "expected some sort of expr, but got %R", obj);
     failed:
@@ -8734,148 +8696,6 @@
 }
 
 int
-obj2ast_slice(PyObject* obj, slice_ty* out, PyArena* arena)
-{
-    int isinstance;
-
-    PyObject *tmp = NULL;
-    PyObject *tp;
-
-    if (obj == Py_None) {
-        *out = NULL;
-        return 0;
-    }
-    tp = astmodulestate_global->Slice_type;
-    isinstance = PyObject_IsInstance(obj, tp);
-    if (isinstance == -1) {
-        return 1;
-    }
-    if (isinstance) {
-        expr_ty lower;
-        expr_ty upper;
-        expr_ty step;
-
-        if (_PyObject_LookupAttr(obj, astmodulestate_global->lower, &tmp) < 0) {
-            return 1;
-        }
-        if (tmp == NULL || tmp == Py_None) {
-            Py_CLEAR(tmp);
-            lower = NULL;
-        }
-        else {
-            int res;
-            res = obj2ast_expr(tmp, &lower, arena);
-            if (res != 0) goto failed;
-            Py_CLEAR(tmp);
-        }
-        if (_PyObject_LookupAttr(obj, astmodulestate_global->upper, &tmp) < 0) {
-            return 1;
-        }
-        if (tmp == NULL || tmp == Py_None) {
-            Py_CLEAR(tmp);
-            upper = NULL;
-        }
-        else {
-            int res;
-            res = obj2ast_expr(tmp, &upper, arena);
-            if (res != 0) goto failed;
-            Py_CLEAR(tmp);
-        }
-        if (_PyObject_LookupAttr(obj, astmodulestate_global->step, &tmp) < 0) {
-            return 1;
-        }
-        if (tmp == NULL || tmp == Py_None) {
-            Py_CLEAR(tmp);
-            step = NULL;
-        }
-        else {
-            int res;
-            res = obj2ast_expr(tmp, &step, arena);
-            if (res != 0) goto failed;
-            Py_CLEAR(tmp);
-        }
-        *out = Slice(lower, upper, step, arena);
-        if (*out == NULL) goto failed;
-        return 0;
-    }
-    tp = astmodulestate_global->ExtSlice_type;
-    isinstance = PyObject_IsInstance(obj, tp);
-    if (isinstance == -1) {
-        return 1;
-    }
-    if (isinstance) {
-        asdl_seq* dims;
-
-        if (_PyObject_LookupAttr(obj, astmodulestate_global->dims, &tmp) < 0) {
-            return 1;
-        }
-        if (tmp == NULL) {
-            PyErr_SetString(PyExc_TypeError, "required field \"dims\" missing from ExtSlice");
-            return 1;
-        }
-        else {
-            int res;
-            Py_ssize_t len;
-            Py_ssize_t i;
-            if (!PyList_Check(tmp)) {
-                PyErr_Format(PyExc_TypeError, "ExtSlice field \"dims\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
-                goto failed;
-            }
-            len = PyList_GET_SIZE(tmp);
-            dims = _Py_asdl_seq_new(len, arena);
-            if (dims == NULL) goto failed;
-            for (i = 0; i < len; i++) {
-                slice_ty val;
-                PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
-                Py_INCREF(tmp2);
-                res = obj2ast_slice(tmp2, &val, arena);
-                Py_DECREF(tmp2);
-                if (res != 0) goto failed;
-                if (len != PyList_GET_SIZE(tmp)) {
-                    PyErr_SetString(PyExc_RuntimeError, "ExtSlice field \"dims\" changed size during iteration");
-                    goto failed;
-                }
-                asdl_seq_SET(dims, i, val);
-            }
-            Py_CLEAR(tmp);
-        }
-        *out = ExtSlice(dims, arena);
-        if (*out == NULL) goto failed;
-        return 0;
-    }
-    tp = astmodulestate_global->Index_type;
-    isinstance = PyObject_IsInstance(obj, tp);
-    if (isinstance == -1) {
-        return 1;
-    }
-    if (isinstance) {
-        expr_ty value;
-
-        if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
-            return 1;
-        }
-        if (tmp == NULL) {
-            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Index");
-            return 1;
-        }
-        else {
-            int res;
-            res = obj2ast_expr(tmp, &value, arena);
-            if (res != 0) goto failed;
-            Py_CLEAR(tmp);
-        }
-        *out = Index(value, arena);
-        if (*out == NULL) goto failed;
-        return 0;
-    }
-
-    PyErr_Format(PyExc_TypeError, "expected some sort of slice, but got %R", obj);
-    failed:
-    Py_XDECREF(tmp);
-    return 1;
-}
-
-int
 obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena)
 {
     int isinstance;
@@ -10187,6 +10007,10 @@
         goto error;
     }
     Py_INCREF(astmodulestate(m)->Tuple_type);
+    if (PyModule_AddObject(m, "Slice", astmodulestate_global->Slice_type) < 0) {
+        goto error;
+    }
+    Py_INCREF(astmodulestate(m)->Slice_type);
     if (PyModule_AddObject(m, "expr_context",
         astmodulestate_global->expr_context_type) < 0) {
         goto error;
@@ -10218,23 +10042,6 @@
         goto error;
     }
     Py_INCREF(astmodulestate(m)->Param_type);
-    if (PyModule_AddObject(m, "slice", astmodulestate_global->slice_type) < 0) {
-        goto error;
-    }
-    Py_INCREF(astmodulestate(m)->slice_type);
-    if (PyModule_AddObject(m, "Slice", astmodulestate_global->Slice_type) < 0) {
-        goto error;
-    }
-    Py_INCREF(astmodulestate(m)->Slice_type);
-    if (PyModule_AddObject(m, "ExtSlice", astmodulestate_global->ExtSlice_type)
-        < 0) {
-        goto error;
-    }
-    Py_INCREF(astmodulestate(m)->ExtSlice_type);
-    if (PyModule_AddObject(m, "Index", astmodulestate_global->Index_type) < 0) {
-        goto error;
-    }
-    Py_INCREF(astmodulestate(m)->Index_type);
     if (PyModule_AddObject(m, "boolop", astmodulestate_global->boolop_type) <
         0) {
         goto error;
diff --git a/Python/ast.c b/Python/ast.c
index 43b50c5..62ee60a 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -40,31 +40,6 @@
 }
 
 static int
-validate_slice(slice_ty slice)
-{
-    switch (slice->kind) {
-    case Slice_kind:
-        return (!slice->v.Slice.lower || validate_expr(slice->v.Slice.lower, Load)) &&
-            (!slice->v.Slice.upper || validate_expr(slice->v.Slice.upper, Load)) &&
-            (!slice->v.Slice.step || validate_expr(slice->v.Slice.step, Load));
-    case ExtSlice_kind: {
-        Py_ssize_t i;
-        if (!validate_nonempty_seq(slice->v.ExtSlice.dims, "dims", "ExtSlice"))
-            return 0;
-        for (i = 0; i < asdl_seq_LEN(slice->v.ExtSlice.dims); i++)
-            if (!validate_slice(asdl_seq_GET(slice->v.ExtSlice.dims, i)))
-                return 0;
-        return 1;
-    }
-    case Index_kind:
-        return validate_expr(slice->v.Index.value, Load);
-    default:
-        PyErr_SetString(PyExc_SystemError, "unknown slice node");
-        return 0;
-    }
-}
-
-static int
 validate_keywords(asdl_seq *keywords)
 {
     Py_ssize_t i;
@@ -309,10 +284,14 @@
     case Attribute_kind:
         return validate_expr(exp->v.Attribute.value, Load);
     case Subscript_kind:
-        return validate_slice(exp->v.Subscript.slice) &&
+        return validate_expr(exp->v.Subscript.slice, Load) &&
             validate_expr(exp->v.Subscript.value, Load);
     case Starred_kind:
         return validate_expr(exp->v.Starred.value, ctx);
+    case Slice_kind:
+        return (!exp->v.Slice.lower || validate_expr(exp->v.Slice.lower, Load)) &&
+            (!exp->v.Slice.upper || validate_expr(exp->v.Slice.upper, Load)) &&
+            (!exp->v.Slice.step || validate_expr(exp->v.Slice.step, Load));
     case List_kind:
         return validate_exprs(exp->v.List.elts, ctx, 0);
     case Tuple_kind:
@@ -2471,7 +2450,7 @@
     }
 }
 
-static slice_ty
+static expr_ty
 ast_for_slice(struct compiling *c, const node *n)
 {
     node *ch;
@@ -2485,13 +2464,7 @@
     */
     ch = CHILD(n, 0);
     if (NCH(n) == 1 && TYPE(ch) == test) {
-        /* 'step' variable hold no significance in terms of being used over
-           other vars */
-        step = ast_for_expr(c, ch);
-        if (!step)
-            return NULL;
-
-        return Index(step, c->c_arena);
+        return ast_for_expr(c, ch);
     }
 
     if (TYPE(ch) == test) {
@@ -2533,7 +2506,8 @@
         }
     }
 
-    return Slice(lower, upper, step, c->c_arena);
+    return Slice(lower, upper, step, LINENO(n), n->n_col_offset,
+                 n->n_end_lineno, n->n_end_col_offset, c->c_arena);
 }
 
 static expr_ty
@@ -2621,7 +2595,7 @@
         REQ(CHILD(n, 2), RSQB);
         n = CHILD(n, 1);
         if (NCH(n) == 1) {
-            slice_ty slc = ast_for_slice(c, CHILD(n, 0));
+            expr_ty slc = ast_for_slice(c, CHILD(n, 0));
             if (!slc)
                 return NULL;
             return Subscript(left_expr, slc, Load, LINENO(start), start->n_col_offset,
@@ -2629,47 +2603,27 @@
                              c->c_arena);
         }
         else {
-            /* The grammar is ambiguous here. The ambiguity is resolved
-               by treating the sequence as a tuple literal if there are
-               no slice features.
-            */
-            Py_ssize_t j;
-            slice_ty slc;
-            expr_ty e;
-            int simple = 1;
-            asdl_seq *slices, *elts;
-            slices = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
-            if (!slices)
+            int j;
+            expr_ty slc, e;
+            asdl_seq *elts;
+            elts = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
+            if (!elts)
                 return NULL;
             for (j = 0; j < NCH(n); j += 2) {
                 slc = ast_for_slice(c, CHILD(n, j));
                 if (!slc)
                     return NULL;
-                if (slc->kind != Index_kind)
-                    simple = 0;
-                asdl_seq_SET(slices, j / 2, slc);
-            }
-            if (!simple) {
-                return Subscript(left_expr, ExtSlice(slices, c->c_arena),
-                                 Load, LINENO(start), start->n_col_offset,
-                                 n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena);
-            }
-            /* extract Index values and put them in a Tuple */
-            elts = _Py_asdl_seq_new(asdl_seq_LEN(slices), c->c_arena);
-            if (!elts)
-                return NULL;
-            for (j = 0; j < asdl_seq_LEN(slices); ++j) {
-                slc = (slice_ty)asdl_seq_GET(slices, j);
-                assert(slc->kind == Index_kind  && slc->v.Index.value);
-                asdl_seq_SET(elts, j, slc->v.Index.value);
+                asdl_seq_SET(elts, j / 2, slc);
             }
             e = Tuple(elts, Load, LINENO(n), n->n_col_offset,
-                      n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+                      n->n_end_lineno, n->n_end_col_offset,
+                      c->c_arena);
             if (!e)
                 return NULL;
-            return Subscript(left_expr, Index(e, c->c_arena),
+            return Subscript(left_expr, e,
                              Load, LINENO(start), start->n_col_offset,
-                             n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena);
+                             n_copy->n_end_lineno, n_copy->n_end_col_offset,
+                             c->c_arena);
         }
     }
 }
diff --git a/Python/ast_opt.c b/Python/ast_opt.c
index 39e164a..7a2b6e6 100644
--- a/Python/ast_opt.c
+++ b/Python/ast_opt.c
@@ -310,20 +310,16 @@
 {
     PyObject *newval;
     expr_ty arg, idx;
-    slice_ty slice;
 
     arg = node->v.Subscript.value;
-    slice = node->v.Subscript.slice;
+    idx = node->v.Subscript.slice;
     if (node->v.Subscript.ctx != Load ||
             arg->kind != Constant_kind ||
-            /* TODO: handle other types of slices */
-            slice->kind != Index_kind ||
-            slice->v.Index.value->kind != Constant_kind)
+            idx->kind != Constant_kind)
     {
         return 1;
     }
 
-    idx = slice->v.Index.value;
     newval = PyObject_GetItem(arg->v.Constant.value, idx->v.Constant.value);
     return make_const(node, newval, arena);
 }
@@ -395,7 +391,6 @@
 static int astfold_arguments(arguments_ty node_, PyArena *ctx_, int optimize_);
 static int astfold_comprehension(comprehension_ty node_, PyArena *ctx_, int optimize_);
 static int astfold_keyword(keyword_ty node_, PyArena *ctx_, int optimize_);
-static int astfold_slice(slice_ty node_, PyArena *ctx_, int optimize_);
 static int astfold_arg(arg_ty node_, PyArena *ctx_, int optimize_);
 static int astfold_withitem(withitem_ty node_, PyArena *ctx_, int optimize_);
 static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, int optimize_);
@@ -548,12 +543,17 @@
         break;
     case Subscript_kind:
         CALL(astfold_expr, expr_ty, node_->v.Subscript.value);
-        CALL(astfold_slice, slice_ty, node_->v.Subscript.slice);
+        CALL(astfold_expr, expr_ty, node_->v.Subscript.slice);
         CALL(fold_subscr, expr_ty, node_);
         break;
     case Starred_kind:
         CALL(astfold_expr, expr_ty, node_->v.Starred.value);
         break;
+    case Slice_kind:
+        CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.lower);
+        CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.upper);
+        CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.step);
+        break;
     case List_kind:
         CALL_SEQ(astfold_expr, expr_ty, node_->v.List.elts);
         break;
@@ -573,27 +573,6 @@
 }
 
 static int
-astfold_slice(slice_ty node_, PyArena *ctx_, int optimize_)
-{
-    switch (node_->kind) {
-    case Slice_kind:
-        CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.lower);
-        CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.upper);
-        CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.step);
-        break;
-    case ExtSlice_kind:
-        CALL_SEQ(astfold_slice, slice_ty, node_->v.ExtSlice.dims);
-        break;
-    case Index_kind:
-        CALL(astfold_expr, expr_ty, node_->v.Index.value);
-        break;
-    default:
-        break;
-    }
-    return 1;
-}
-
-static int
 astfold_keyword(keyword_ty node_, PyArena *ctx_, int optimize_)
 {
     CALL(astfold_expr, expr_ty, node_->value);
diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c
index bd9c139..5ecd1b0 100644
--- a/Python/ast_unparse.c
+++ b/Python/ast_unparse.c
@@ -17,7 +17,7 @@
 static int
 append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e);
 static int
-append_ast_slice(_PyUnicodeWriter *writer, slice_ty slice);
+append_ast_slice(_PyUnicodeWriter *writer, expr_ty e);
 
 static int
 append_charp(_PyUnicodeWriter *writer, const char *charp)
@@ -718,62 +718,31 @@
 }
 
 static int
-append_ast_simple_slice(_PyUnicodeWriter *writer, slice_ty slice)
+append_ast_slice(_PyUnicodeWriter *writer, expr_ty e)
 {
-    if (slice->v.Slice.lower) {
-        APPEND_EXPR(slice->v.Slice.lower, PR_TEST);
+    if (e->v.Slice.lower) {
+        APPEND_EXPR(e->v.Slice.lower, PR_TEST);
     }
 
     APPEND_STR(":");
 
-    if (slice->v.Slice.upper) {
-        APPEND_EXPR(slice->v.Slice.upper, PR_TEST);
+    if (e->v.Slice.upper) {
+        APPEND_EXPR(e->v.Slice.upper, PR_TEST);
     }
 
-    if (slice->v.Slice.step) {
+    if (e->v.Slice.step) {
         APPEND_STR(":");
-        APPEND_EXPR(slice->v.Slice.step, PR_TEST);
+        APPEND_EXPR(e->v.Slice.step, PR_TEST);
     }
     return 0;
 }
 
 static int
-append_ast_ext_slice(_PyUnicodeWriter *writer, slice_ty slice)
-{
-    Py_ssize_t i, dims_count;
-    dims_count = asdl_seq_LEN(slice->v.ExtSlice.dims);
-    for (i = 0; i < dims_count; i++) {
-        APPEND_STR_IF(i > 0, ", ");
-        APPEND(slice, (slice_ty)asdl_seq_GET(slice->v.ExtSlice.dims, i));
-    }
-    APPEND_STR_IF(dims_count == 1, ",");
-    return 0;
-}
-
-static int
-append_ast_slice(_PyUnicodeWriter *writer, slice_ty slice)
-{
-    switch (slice->kind) {
-    case Slice_kind:
-        return append_ast_simple_slice(writer, slice);
-    case ExtSlice_kind:
-        return append_ast_ext_slice(writer, slice);
-    case Index_kind:
-        APPEND_EXPR(slice->v.Index.value, PR_TUPLE);
-        return 0;
-    default:
-        PyErr_SetString(PyExc_SystemError,
-                        "unexpected slice kind");
-        return -1;
-    }
-}
-
-static int
 append_ast_subscript(_PyUnicodeWriter *writer, expr_ty e)
 {
     APPEND_EXPR(e->v.Subscript.value, PR_ATOM);
     APPEND_STR("[");
-    APPEND(slice, e->v.Subscript.slice);
+    APPEND_EXPR(e->v.Subscript.slice, PR_TUPLE);
     APPEND_STR_FINISH("]");
 }
 
@@ -878,6 +847,8 @@
         return append_ast_subscript(writer, e);
     case Starred_kind:
         return append_ast_starred(writer, e);
+    case Slice_kind:
+        return append_ast_slice(writer, e);
     case Name_kind:
         return _PyUnicodeWriter_WriteStr(writer, e->v.Name.id);
     case List_kind:
diff --git a/Python/compile.c b/Python/compile.c
index f228e16..55333b3 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -193,8 +193,8 @@
 static int compiler_visit_expr(struct compiler *, expr_ty);
 static int compiler_augassign(struct compiler *, stmt_ty);
 static int compiler_annassign(struct compiler *, stmt_ty);
-static int compiler_visit_slice(struct compiler *, slice_ty,
-                                expr_context_ty);
+static int compiler_subscript(struct compiler *, expr_ty);
+static int compiler_slice(struct compiler *, expr_ty);
 
 static int inplace_binop(struct compiler *, operator_ty);
 static int are_all_items_const(asdl_seq *, Py_ssize_t, Py_ssize_t);
@@ -4045,14 +4045,11 @@
 }
 
 static int
-check_index(struct compiler *c, expr_ty e, slice_ty s)
+check_index(struct compiler *c, expr_ty e, expr_ty s)
 {
     PyObject *v;
 
-    if (s->kind != Index_kind) {
-        return 1;
-    }
-    PyTypeObject *index_type = infer_type(s->v.Index.value);
+    PyTypeObject *index_type = infer_type(s);
     if (index_type == NULL
         || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS)
         || index_type == &PySlice_Type) {
@@ -5065,39 +5062,7 @@
         }
         break;
     case Subscript_kind:
-        switch (e->v.Subscript.ctx) {
-        case AugLoad:
-            VISIT(c, expr, e->v.Subscript.value);
-            VISIT_SLICE(c, e->v.Subscript.slice, AugLoad);
-            break;
-        case Load:
-            if (!check_subscripter(c, e->v.Subscript.value)) {
-                return 0;
-            }
-            if (!check_index(c, e->v.Subscript.value, e->v.Subscript.slice)) {
-                return 0;
-            }
-            VISIT(c, expr, e->v.Subscript.value);
-            VISIT_SLICE(c, e->v.Subscript.slice, Load);
-            break;
-        case AugStore:
-            VISIT_SLICE(c, e->v.Subscript.slice, AugStore);
-            break;
-        case Store:
-            VISIT(c, expr, e->v.Subscript.value);
-            VISIT_SLICE(c, e->v.Subscript.slice, Store);
-            break;
-        case Del:
-            VISIT(c, expr, e->v.Subscript.value);
-            VISIT_SLICE(c, e->v.Subscript.slice, Del);
-            break;
-        case Param:
-        default:
-            PyErr_SetString(PyExc_SystemError,
-                "param invalid in subscript expression");
-            return 0;
-        }
-        break;
+        return compiler_subscript(c, e);
     case Starred_kind:
         switch (e->v.Starred.ctx) {
         case Store:
@@ -5109,6 +5074,9 @@
             return compiler_error(c,
                 "can't use starred expression here");
         }
+        break;
+    case Slice_kind:
+        return compiler_slice(c, e);
     case Name_kind:
         return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx);
     /* child nodes of List and Tuple will have expr_context set */
@@ -5213,68 +5181,35 @@
 }
 
 static int
-check_ann_slice(struct compiler *c, slice_ty sl)
-{
-    switch(sl->kind) {
-    case Index_kind:
-        return check_ann_expr(c, sl->v.Index.value);
-    case Slice_kind:
-        if (sl->v.Slice.lower && !check_ann_expr(c, sl->v.Slice.lower)) {
-            return 0;
-        }
-        if (sl->v.Slice.upper && !check_ann_expr(c, sl->v.Slice.upper)) {
-            return 0;
-        }
-        if (sl->v.Slice.step && !check_ann_expr(c, sl->v.Slice.step)) {
-            return 0;
-        }
-        break;
-    default:
-        PyErr_SetString(PyExc_SystemError,
-                        "unexpected slice kind");
-        return 0;
-    }
-    return 1;
-}
-
-static int
-check_ann_subscr(struct compiler *c, slice_ty sl)
+check_ann_subscr(struct compiler *c, expr_ty e)
 {
     /* We check that everything in a subscript is defined at runtime. */
-    Py_ssize_t i, n;
-
-    switch (sl->kind) {
-    case Index_kind:
+    switch (e->kind) {
     case Slice_kind:
-        if (!check_ann_slice(c, sl)) {
+        if (e->v.Slice.lower && !check_ann_expr(c, e->v.Slice.lower)) {
             return 0;
         }
-        break;
-    case ExtSlice_kind:
-        n = asdl_seq_LEN(sl->v.ExtSlice.dims);
+        if (e->v.Slice.upper && !check_ann_expr(c, e->v.Slice.upper)) {
+            return 0;
+        }
+        if (e->v.Slice.step && !check_ann_expr(c, e->v.Slice.step)) {
+            return 0;
+        }
+        return 1;
+    case Tuple_kind: {
+        /* extended slice */
+        asdl_seq *elts = e->v.Tuple.elts;
+        Py_ssize_t i, n = asdl_seq_LEN(elts);
         for (i = 0; i < n; i++) {
-            slice_ty subsl = (slice_ty)asdl_seq_GET(sl->v.ExtSlice.dims, i);
-            switch (subsl->kind) {
-            case Index_kind:
-            case Slice_kind:
-                if (!check_ann_slice(c, subsl)) {
-                    return 0;
-                }
-                break;
-            case ExtSlice_kind:
-            default:
-                PyErr_SetString(PyExc_SystemError,
-                                "extended slice invalid in nested slice");
+            if (!check_ann_subscr(c, asdl_seq_GET(elts, i))) {
                 return 0;
             }
         }
-        break;
-    default:
-        PyErr_Format(PyExc_SystemError,
-                     "invalid subscript kind %d", sl->kind);
-        return 0;
+        return 1;
     }
-    return 1;
+    default:
+        return check_ann_expr(c, e);
+    }
 }
 
 static int
@@ -5400,12 +5335,20 @@
 }
 
 static int
-compiler_handle_subscr(struct compiler *c, const char *kind,
-                       expr_context_ty ctx)
+compiler_subscript(struct compiler *c, expr_ty e)
 {
+    expr_context_ty ctx = e->v.Subscript.ctx;
     int op = 0;
 
-    /* XXX this code is duplicated */
+    if (ctx == Load) {
+        if (!check_subscripter(c, e->v.Subscript.value)) {
+            return 0;
+        }
+        if (!check_index(c, e->v.Subscript.value, e->v.Subscript.slice)) {
+            return 0;
+        }
+    }
+
     switch (ctx) {
         case AugLoad: /* fall through to Load */
         case Load:    op = BINARY_SUBSCR; break;
@@ -5413,23 +5356,26 @@
         case Store:   op = STORE_SUBSCR; break;
         case Del:     op = DELETE_SUBSCR; break;
         case Param:
-            PyErr_Format(PyExc_SystemError,
-                         "invalid %s kind %d in subscript\n",
-                         kind, ctx);
+            PyErr_SetString(PyExc_SystemError,
+                "param invalid in subscript expression");
             return 0;
     }
-    if (ctx == AugLoad) {
-        ADDOP(c, DUP_TOP_TWO);
-    }
-    else if (ctx == AugStore) {
+    if (ctx == AugStore) {
         ADDOP(c, ROT_THREE);
     }
+    else {
+        VISIT(c, expr, e->v.Subscript.value);
+        VISIT(c, expr, e->v.Subscript.slice);
+        if (ctx == AugLoad) {
+            ADDOP(c, DUP_TOP_TWO);
+        }
+    }
     ADDOP(c, op);
     return 1;
 }
 
 static int
-compiler_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
+compiler_slice(struct compiler *c, expr_ty s)
 {
     int n = 2;
     assert(s->kind == Slice_kind);
@@ -5457,64 +5403,6 @@
     return 1;
 }
 
-static int
-compiler_visit_nested_slice(struct compiler *c, slice_ty s,
-                            expr_context_ty ctx)
-{
-    switch (s->kind) {
-    case Slice_kind:
-        return compiler_slice(c, s, ctx);
-    case Index_kind:
-        VISIT(c, expr, s->v.Index.value);
-        break;
-    case ExtSlice_kind:
-    default:
-        PyErr_SetString(PyExc_SystemError,
-                        "extended slice invalid in nested slice");
-        return 0;
-    }
-    return 1;
-}
-
-static int
-compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
-{
-    const char * kindname = NULL;
-    switch (s->kind) {
-    case Index_kind:
-        kindname = "index";
-        if (ctx != AugStore) {
-            VISIT(c, expr, s->v.Index.value);
-        }
-        break;
-    case Slice_kind:
-        kindname = "slice";
-        if (ctx != AugStore) {
-            if (!compiler_slice(c, s, ctx))
-                return 0;
-        }
-        break;
-    case ExtSlice_kind:
-        kindname = "extended slice";
-        if (ctx != AugStore) {
-            Py_ssize_t i, n = asdl_seq_LEN(s->v.ExtSlice.dims);
-            for (i = 0; i < n; i++) {
-                slice_ty sub = (slice_ty)asdl_seq_GET(
-                    s->v.ExtSlice.dims, i);
-                if (!compiler_visit_nested_slice(c, sub, ctx))
-                    return 0;
-            }
-            ADDOP_I(c, BUILD_TUPLE, n);
-        }
-        break;
-    default:
-        PyErr_Format(PyExc_SystemError,
-                     "invalid subscript kind %d", s->kind);
-        return 0;
-    }
-    return compiler_handle_subscr(c, kindname, ctx);
-}
-
 /* End of the compiler section, beginning of the assembler section */
 
 /* do depth-first search of basic block graph, starting with block.
diff --git a/Python/symtable.c b/Python/symtable.c
index 290e41b..014570e 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -202,7 +202,6 @@
 static int symtable_visit_alias(struct symtable *st, alias_ty);
 static int symtable_visit_comprehension(struct symtable *st, comprehension_ty);
 static int symtable_visit_keyword(struct symtable *st, keyword_ty);
-static int symtable_visit_slice(struct symtable *st, slice_ty);
 static int symtable_visit_params(struct symtable *st, asdl_seq *args);
 static int symtable_visit_argannotations(struct symtable *st, asdl_seq *args);
 static int symtable_implicit_arg(struct symtable *st, int pos);
@@ -1632,11 +1631,19 @@
         break;
     case Subscript_kind:
         VISIT(st, expr, e->v.Subscript.value);
-        VISIT(st, slice, e->v.Subscript.slice);
+        VISIT(st, expr, e->v.Subscript.slice);
         break;
     case Starred_kind:
         VISIT(st, expr, e->v.Starred.value);
         break;
+    case Slice_kind:
+        if (e->v.Slice.lower)
+            VISIT(st, expr, e->v.Slice.lower)
+        if (e->v.Slice.upper)
+            VISIT(st, expr, e->v.Slice.upper)
+        if (e->v.Slice.step)
+            VISIT(st, expr, e->v.Slice.step)
+        break;
     case Name_kind:
         if (!symtable_add_def(st, e->v.Name.id,
                               e->v.Name.ctx == Load ? USE : DEF_LOCAL))
@@ -1842,28 +1849,6 @@
 
 
 static int
-symtable_visit_slice(struct symtable *st, slice_ty s)
-{
-    switch (s->kind) {
-    case Slice_kind:
-        if (s->v.Slice.lower)
-            VISIT(st, expr, s->v.Slice.lower)
-        if (s->v.Slice.upper)
-            VISIT(st, expr, s->v.Slice.upper)
-        if (s->v.Slice.step)
-            VISIT(st, expr, s->v.Slice.step)
-        break;
-    case ExtSlice_kind:
-        VISIT_SEQ(st, slice, s->v.ExtSlice.dims)
-        break;
-    case Index_kind:
-        VISIT(st, expr, s->v.Index.value)
-        break;
-    }
-    return 1;
-}
-
-static int
 symtable_handle_comprehension(struct symtable *st, expr_ty e,
                               identifier scope_name, asdl_seq *generators,
                               expr_ty elt, expr_ty value)