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:
github-actions[bot]: Hello. You may have forgotten to update the changelog!
Please edit [`doc/releases/changelog-dev.md`](/PennyLaneAI/pennylane/blob/master/doc/releases/changelog-dev.md) with:
* A one-to-two sentence description of the change. You may include a small working example for new features.
* A link back to this PR.
* Your name (or GitHub username) in the contributors section.
codecov[bot]: # [Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3266?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) Report
> Merging [#3266](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3266?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (dee43d7) into [master](https://codecov.io/gh/PennyLaneAI/pennylane/commit/011fe74a8b715db28eaf40ef9c2ed11095402d43?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (011fe74) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.

```diff
@@           Coverage Diff           @@
##           master    #3266   +/-   ##
=======================================
  Coverage   99.71%   99.71%           
=======================================
  Files         288      288           
  Lines       26011    26012    +1     
=======================================
+ Hits        25937    25938    +1     
  Misses         74       74           
```


| [Impacted Files](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3266?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) | Coverage Δ | |
|---|---|---|
| [pennylane/devices/default\_qubit.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3266/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2RldmljZXMvZGVmYXVsdF9xdWJpdC5weQ==) | `100.00% <100.00%> (ø)` | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI)


Patch:
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index ed8709038..a19551983 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -667,6 +667,10 @@ Users can specify the control wires as well as the values to control the operati
 * Fixed a bug where `qml.BasisEmbedding` was not jit-compilable with JAX.
   [(#3239)](https://github.com/PennyLaneAI/pennylane/pull/3239)
 
+* Fixed a bug where `qml.expval(qml.Hamiltonian())` would not raise an error
+  if the Hamiltonian involved some wires that are not present on the device.
+  [(#3266)](https://github.com/PennyLaneAI/pennylane/pull/3266)
+
 <h3>Contributors</h3>
 
 This release contains contributions from (in alphabetical order):
diff --git a/pennylane/devices/default_qubit.py b/pennylane/devices/default_qubit.py
index d84bf2307..bc008c991 100644
--- a/pennylane/devices/default_qubit.py
+++ b/pennylane/devices/default_qubit.py
@@ -533,6 +533,7 @@ class DefaultQubit(QubitDevice):
         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
index 378fef111..d6a6703bb 100644
--- a/tests/devices/test_default_qubit.py
+++ b/tests/devices/test_default_qubit.py
@@ -79,8 +79,6 @@ U_cswap = np.array(
     ]
 )
 
-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 @@ class TestHamiltonianSupport:
         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``."""