Repository: scikit-hep/awkward

Issue:
`ak.cartesian` followed by indexing operation over-touches data
### Version of Awkward Array

main + #2370 & #2373

### Description and code to reproduce

```python3
import json
import awkward as ak


def delta_r2(a, b):
    return (a.eta - b.eta) ** 2 + (a.phi - b.phi) ** 2


fromjson = {
    "class": "RecordArray",
    "fields": ["muon", "jet"],
    "contents": [
        {
            "class": "ListOffsetArray",
            "offsets": "i64",
            "content": {
                "class": "RecordArray",
                "fields": ["pt", "eta", "phi", "crossref"],
                "contents": [
                    {
                        "class": "NumpyArray",
                        "primitive": "int64",
                        "inner_shape": [],
                        "parameters": {},
                        "form_key": "muon_pt!",
                    },
                    {
                        "class": "NumpyArray",
                        "primitive": "int64",
                        "inner_shape": [],
                        "parameters": {},
                        "form_key": "muon_eta!",
                    },
                    {
                        "class": "NumpyArray",
                        "primitive": "int64",
                        "inner_shape": [],
                        "parameters": {},
                        "form_key": "muon_phi!",
                    },
                    {
                        "class": "ListOffsetArray",
                        "offsets": "i64",
                        "content": {
                            "class": "NumpyArray",
                            "primitive": "int64",
                            "inner_shape": [],
                            "parameters": {},
                            "form_key": "muon_crossref_content!",
                        },
                        "parameters": {},
                        "form_key": "muon_crossref_index!",
                    },
                ],
                "parameters": {},
                "form_key": "muon_record!",
            },
            "parameters": {},
            "form_key": "muon_list!",
        },
        {
            "class": "ListOffsetArray",
            "offsets": "i64",
            "content": {
                "class": "RecordArray",
                "fields": ["pt", "eta", "phi", "crossref", "thing1"],
                "contents": [
                    {
                        "class": "NumpyArray",
                        "primitive": "int64",
                        "inner_shape": [],
                        "parameters": {},
                        "form_key": "jet_pt!",
                    },
                    {
                        "class": "NumpyArray",
                        "primitive": "int64",
                        "inner_shape": [],
                        "parameters": {},
                        "form_key": "jet_eta!",
                    },
                    {
                        "class": "NumpyArray",
                        "primitive": "int64",
                        "inner_shape": [],
                        "parameters": {},
                        "form_key": "jet_phi!",
                    },
                    {
                        "class": "ListOffsetArray",
                        "offsets": "i64",
                        "content": {
                            "class": "NumpyArray",
                            "primitive": "int64",
                            "inner_shape": [],
                            "parameters": {},
                            "form_key": "jet_crossref_content!",
                        },
                        "parameters": {},
                        "form_key": "jet_crossref_index!",
                    },
                    {
                        "class": "NumpyArray",
                        "primitive": "int64",
                        "inner_shape": [],
                        "parameters": {},
                        "form_key": "jet_thing1!",
                    },
                ],
                "parameters": {},
                "form_key": "jet_record!",
            },
            "parameters": {},
            "form_key": "jet_list!",
        },
    ],
    "parameters": {},
    "form_key": "outer!",
}

form = ak.forms.from_json(json.dumps(fromjson))

ttlayout, report = ak._nplikes.typetracer.typetracer_with_report(form)

ttarray = ak.Array(ttlayout)

a = ak.cartesian([ttarray.muon, ttarray.jet], axis=1, nested=True)

print("ab>>>", report.data_touched, "\n")

mval = delta_r2(a["0"], a["1"])

print("dr>>>>", report.data_touched, "\n")

mmin = ak.argmin(mval, axis=2)

print("mmin>>", report.data_touched, "\n")

ak.firsts(a["1"][mmin], axis=2).pt

print("pt>>>>", report.data_touched, "\n")
```

produces:
```
ab>>> ['muon_list!', 'jet_list!'] 

dr>>>> ['muon_list!', 'jet_list!', 'muon_eta!', 'jet_eta!', 'muon_phi!', 'jet_phi!'] 

mmin>> ['muon_list!', 'jet_list!', 'muon_eta!', 'jet_eta!', 'muon_phi!', 'jet_phi!'] 

pt>>>> ['muon_list!', 'jet_list!', 'muon_eta!', 'jet_eta!', 'muon_phi!', 'jet_phi!', 'jet_pt!', 'jet_crossref_index!', 'jet_crossref_content!', 'jet_thing1!'] 

```

Which is touching everything in the "jet" object in this case. It should only touch "jet_pt!" in addition to what is required for the matching criteria (delta_r in this case, could be anything).
Follow up to #2372


Discussion:

Resolving patch:
diff --git a/src/awkward/contents/listarray.py b/src/awkward/contents/listarray.py
--- a/src/awkward/contents/listarray.py
+++ b/src/awkward/contents/listarray.py
@@ -622,8 +622,6 @@ def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail):
                 out = ak.contents.IndexedOptionArray.simplified(
                     missing_trim, content, parameters=self._parameters
                 )
-                if isinstance(self._backend.nplike, TypeTracer):
-                    out = out.to_typetracer()
                 return ak.contents.ListOffsetArray(
                     largeoffsets,
                     out,


Test patch:
diff --git a/tests/test_2374_cartesian_touching.py b/tests/test_2374_cartesian_touching.py
new file mode 100644
--- /dev/null
+++ b/tests/test_2374_cartesian_touching.py
@@ -0,0 +1,159 @@
+import awkward as ak
+
+
+def delta_r2(a, b):
+    return (a.eta - b.eta) ** 2 + (a.phi - b.phi) ** 2
+
+
+def test():
+    form = ak.forms.from_dict(
+        {
+            "class": "RecordArray",
+            "fields": ["muon", "jet"],
+            "contents": [
+                {
+                    "class": "ListOffsetArray",
+                    "offsets": "i64",
+                    "content": {
+                        "class": "RecordArray",
+                        "fields": ["pt", "eta", "phi", "crossref"],
+                        "contents": [
+                            {
+                                "class": "NumpyArray",
+                                "primitive": "int64",
+                                "inner_shape": [],
+                                "parameters": {},
+                                "form_key": "muon_pt!",
+                            },
+                            {
+                                "class": "NumpyArray",
+                                "primitive": "int64",
+                                "inner_shape": [],
+                                "parameters": {},
+                                "form_key": "muon_eta!",
+                            },
+                            {
+                                "class": "NumpyArray",
+                                "primitive": "int64",
+                                "inner_shape": [],
+                                "parameters": {},
+                                "form_key": "muon_phi!",
+                            },
+                            {
+                                "class": "ListOffsetArray",
+                                "offsets": "i64",
+                                "content": {
+                                    "class": "NumpyArray",
+                                    "primitive": "int64",
+                                    "inner_shape": [],
+                                    "parameters": {},
+                                    "form_key": "muon_crossref_content!",
+                                },
+                                "parameters": {},
+                                "form_key": "muon_crossref_index!",
+                            },
+                        ],
+                        "parameters": {},
+                        "form_key": "muon_record!",
+                    },
+                    "parameters": {},
+                    "form_key": "muon_list!",
+                },
+                {
+                    "class": "ListOffsetArray",
+                    "offsets": "i64",
+                    "content": {
+                        "class": "RecordArray",
+                        "fields": ["pt", "eta", "phi", "crossref", "thing1"],
+                        "contents": [
+                            {
+                                "class": "NumpyArray",
+                                "primitive": "int64",
+                                "inner_shape": [],
+                                "parameters": {},
+                                "form_key": "jet_pt!",
+                            },
+                            {
+                                "class": "NumpyArray",
+                                "primitive": "int64",
+                                "inner_shape": [],
+                                "parameters": {},
+                                "form_key": "jet_eta!",
+                            },
+                            {
+                                "class": "NumpyArray",
+                                "primitive": "int64",
+                                "inner_shape": [],
+                                "parameters": {},
+                                "form_key": "jet_phi!",
+                            },
+                            {
+                                "class": "ListOffsetArray",
+                                "offsets": "i64",
+                                "content": {
+                                    "class": "NumpyArray",
+                                    "primitive": "int64",
+                                    "inner_shape": [],
+                                    "parameters": {},
+                                    "form_key": "jet_crossref_content!",
+                                },
+                                "parameters": {},
+                                "form_key": "jet_crossref_index!",
+                            },
+                            {
+                                "class": "NumpyArray",
+                                "primitive": "int64",
+                                "inner_shape": [],
+                                "parameters": {},
+                                "form_key": "jet_thing1!",
+                            },
+                        ],
+                        "parameters": {},
+                        "form_key": "jet_record!",
+                    },
+                    "parameters": {},
+                    "form_key": "jet_list!",
+                },
+            ],
+            "parameters": {},
+            "form_key": "outer!",
+        }
+    )
+
+    ttlayout, report = ak._nplikes.typetracer.typetracer_with_report(form)
+
+    ttarray = ak.Array(ttlayout)
+
+    a = ak.cartesian([ttarray.muon, ttarray.jet], axis=1, nested=True)
+
+    mval = delta_r2(a["0"], a["1"])
+
+    assert report.data_touched == [
+        "muon_list!",
+        "jet_list!",
+        "muon_eta!",
+        "jet_eta!",
+        "muon_phi!",
+        "jet_phi!",
+    ]
+
+    mmin = ak.argmin(mval, axis=2)
+    assert report.data_touched == [
+        "muon_list!",
+        "jet_list!",
+        "muon_eta!",
+        "jet_eta!",
+        "muon_phi!",
+        "jet_phi!",
+    ]
+
+    ak.firsts(a["1"][mmin], axis=2)
+
+    assert report.data_touched == [
+        "muon_list!",
+        "jet_list!",
+        "muon_eta!",
+        "jet_eta!",
+        "muon_phi!",
+        "jet_phi!",
+    ]