diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py
index 2f449b4b33d8d..454d029c266f5 100644
--- a/pandas/core/indexes/base.py
+++ b/pandas/core/indexes/base.py
@@ -19,7 +19,7 @@
     ABCSeries, ABCDataFrame,
     ABCMultiIndex,
     ABCPeriodIndex, ABCTimedeltaIndex, ABCDatetimeIndex,
-    ABCDateOffset)
+    ABCDateOffset, ABCIndexClass)
 from pandas.core.dtypes.missing import isna, array_equivalent
 from pandas.core.dtypes.cast import maybe_cast_to_integer_array
 from pandas.core.dtypes.common import (
@@ -522,6 +522,12 @@ def _simple_new(cls, values, name=None, dtype=None, **kwargs):
                     values = cls(values, name=name, dtype=dtype,
                                  **kwargs)._ndarray_values
 
+        if isinstance(values, (ABCSeries, ABCIndexClass)):
+            # Index._data must always be an ndarray.
+            # This is no-copy for when _values is an ndarray,
+            # which should be always at this point.
+            values = np.asarray(values._values)
+
         result = object.__new__(cls)
         result._data = values
         result.name = name
diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py
index 619f60a42e0be..424f6b1f9a77a 100644
--- a/pandas/tests/indexes/test_base.py
+++ b/pandas/tests/indexes/test_base.py
@@ -504,6 +504,13 @@ def test_constructor_cast(self):
         with pytest.raises(ValueError, match=msg):
             Index(["a", "b", "c"], dtype=float)
 
+    def test_constructor_unwraps_index(self, indices):
+        if isinstance(indices, pd.MultiIndex):
+            raise pytest.skip("MultiIndex has no ._data")
+        a = indices
+        b = type(a)(a)
+        tm.assert_equal(a._data, b._data)
+
     def test_view_with_args(self):
 
         restricted = ['unicodeIndex', 'strIndex', 'catIndex', 'boolIndex',
diff --git a/pandas/tests/series/test_operators.py b/pandas/tests/series/test_operators.py
index 4cce26d135443..bcecedc2bba97 100644
--- a/pandas/tests/series/test_operators.py
+++ b/pandas/tests/series/test_operators.py
@@ -189,20 +189,7 @@ def test_scalar_na_logical_ops_corners(self):
         operator.and_,
         operator.or_,
         operator.xor,
-        pytest.param(ops.rand_,
-                     marks=pytest.mark.xfail(reason="GH#22092 Index "
-                                                    "implementation returns "
-                                                    "Index",
-                                             raises=AssertionError,
-                                             strict=True)),
-        pytest.param(ops.ror_,
-                     marks=pytest.mark.xfail(reason="GH#22092 Index "
-                                                    "implementation raises",
-                                             raises=ValueError, strict=True)),
-        pytest.param(ops.rxor,
-                     marks=pytest.mark.xfail(reason="GH#22092 Index "
-                                                    "implementation raises",
-                                             raises=TypeError, strict=True))
+
     ])
     def test_logical_ops_with_index(self, op):
         # GH#22092, GH#19792
@@ -221,6 +208,19 @@ def test_logical_ops_with_index(self, op):
         result = op(ser, idx2)
         assert_series_equal(result, expected)
 
+    @pytest.mark.parametrize("op, expected", [
+        (ops.rand_, pd.Index([False, True])),
+        (ops.ror_, pd.Index([False, True])),
+        (ops.rxor, pd.Index([])),
+    ])
+    def test_reverse_ops_with_index(self, op, expected):
+        # https://github.com/pandas-dev/pandas/pull/23628
+        # multi-set Index ops are buggy, so let's avoid duplicates...
+        ser = Series([True, False])
+        idx = Index([False, True])
+        result = op(ser, idx)
+        tm.assert_index_equal(result, expected)
+
     def test_logical_ops_label_based(self):
         # GH#4947
         # logical ops should be label based