Repository: PennyLaneAI/pennylane

Issue:
[BUG] Wires are not checked when computing the `expval` of a `Hamiltonian` with `shots=None`
### Expected behavior

The attached code should raise the error:
```
pennylane.wires.WireError: Did not find some of the wires (0, 1) on device with wires (0,).
```

### Actual behavior

It runs and returns an incorrect value.

### Additional information

This error is raised only in the `Device.map_wires` method. I guess that in this example this method is never called, and thus the error is never raised.

Should we do a wire check at the beginning of the execution?

### Source code

```shell
import pennylane as qml

device = qml.device("default.qubit", wires=1)

H = 1.5 * qml.PauliZ(0) @ qml.PauliZ(1) + 0.3 * qml.PauliX(1)

@qml.qnode(device)
def circuit():
    return qml.expval(H)

print(circuit())
```


### Tracebacks

_No response_

### System information

```shell
Name: PennyLane
Version: 0.27.0.dev0
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: https://github.com/XanaduAI/pennylane
Author: 
Author-email: 
License: Apache License 2.0
Location: /Users/albertmitjans/Developer/pennylane/.venv/lib/python3.9/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, retworkx, scipy, semantic-version, toml
Required-by: PennyLane-Forest, PennyLane-Lightning, PennyLane-qiskit, PennyLane-SF

Platform info:           macOS-13.0-arm64-arm-64bit
Python version:          3.9.13
Numpy version:           1.23.2
Scipy version:           1.9.0
Installed devices:
- default.gaussian (PennyLane-0.27.0.dev0)
- default.mixed (PennyLane-0.27.0.dev0)
- default.qubit (PennyLane-0.27.0.dev0)
- default.qubit.autograd (PennyLane-0.27.0.dev0)
- default.qubit.jax (PennyLane-0.27.0.dev0)
- default.qubit.tf (PennyLane-0.27.0.dev0)
- default.qubit.torch (PennyLane-0.27.0.dev0)
- default.qutrit (PennyLane-0.27.0.dev0)
- null.qubit (PennyLane-0.27.0.dev0)
- lightning.qubit (PennyLane-Lightning-0.26.0)
- qiskit.aer (PennyLane-qiskit-0.24.0)
- qiskit.basicaer (PennyLane-qiskit-0.24.0)
- qiskit.ibmq (PennyLane-qiskit-0.24.0)
- qiskit.ibmq.circuit_runner (PennyLane-qiskit-0.24.0)
- qiskit.ibmq.sampler (PennyLane-qiskit-0.24.0)
- forest.numpy_wavefunction (PennyLane-Forest-0.24.0)
- forest.qvm (PennyLane-Forest-0.24.0)
- forest.wavefunction (PennyLane-Forest-0.24.0)
- strawberryfields.fock (PennyLane-SF-0.20.1)
- strawberryfields.gaussian (PennyLane-SF-0.20.1)
- strawberryfields.gbs (PennyLane-SF-0.20.1)
- strawberryfields.remote (PennyLane-SF-0.20.1)
- strawberryfields.tf (PennyLane-SF-0.20.1)
```


### Existing GitHub issues

- [X] I have searched existing GitHub issues to make sure the issue does not already exist.


Discussion:

Resolving patch:
diff --git a/pennylane/devices/default_qubit.py b/pennylane/devices/default_qubit.py
--- a/pennylane/devices/default_qubit.py
+++ b/pennylane/devices/default_qubit.py
@@ -533,6 +533,7 @@ def expval(self, observable, shot_range=None, bin_size=None):
         if observable.name in ("Hamiltonian", "SparseHamiltonian"):
             assert self.shots is None, f"{observable.name} must be used with shots=None"
 
+            self.map_wires(observable.wires)
             backprop_mode = (
                 not isinstance(self.state, np.ndarray)
                 or any(not isinstance(d, (float, np.ndarray)) for d in observable.data)


Test patch:
diff --git a/tests/devices/test_default_qubit.py b/tests/devices/test_default_qubit.py
--- a/tests/devices/test_default_qubit.py
+++ b/tests/devices/test_default_qubit.py
@@ -79,8 +79,6 @@
     ]
 )
 
-H = np.array([[1.02789352, 1.61296440 - 0.3498192j], [1.61296440 + 0.3498192j, 1.23920938 + 0j]])
-
 THETA = np.linspace(0.11, 1, 3)
 PHI = np.linspace(0.32, 1, 3)
 VARPHI = np.linspace(0.02, 1, 3)
@@ -2546,6 +2544,17 @@ def test_error_hamiltonian_expval_finite_shots(self):
         with pytest.raises(AssertionError, match="Hamiltonian must be used with shots=None"):
             dev.expval(H)
 
+    def test_error_hamiltonian_expval_wrong_wires(self):
+        """Tests that expval fails if Hamiltonian uses non-device wires."""
+        dev = qml.device("default.qubit", wires=2, shots=None)
+        H = qml.Hamiltonian([0.1, 0.2, 0.3], [qml.PauliX(0), qml.PauliZ(1), qml.PauliY(2)])
+
+        with pytest.raises(
+            WireError,
+            match=r"Did not find some of the wires \(0, 1, 2\) on device with wires \(0, 1\).",
+        ):
+            dev.expval(H)
+
 
 class TestGetBatchSize:
     """Tests for the helper method ``_get_batch_size`` of ``QubitDevice``."""