Repository: Qiskit/qiskit-terra (python)

Issue:
Wrong decomposition rule when decomposing into a single-qubit instruction
### Environment

- **Qiskit Terra version**: 0.21.1
- **Python version**: 3.9.13
- **Operating system**: macOS Monterey


### What is happening?

I use placeholder instructions with one or more qubits and clbits to create circuits in different configurations.
The placeholders are created with the maximum amount of qubits and clbits needed, which might be more than needed for some specific configurations.

However, if I put *one single-qubit instruction* into a placeholder with 1 qubit and *C* clbits, `circuit.decompose()` fails with 
```
qiskit.dagcircuit.exceptions.DAGCircuitError: 
'Cannot replace node of width (1 qubits, C clbits) with instruction of mismatched width (1 qubits, 0 clbits).'
```

### How can we reproduce the issue?

```python
from qiskit import QuantumCircuit

placeholder = QuantumCircuit(1, 1)
placeholder.h(0)
# placeholder.x(0) # uncomment this line to make the example work

pld_instr = placeholder.to_instruction()

circuit = QuantumCircuit(3, 3)
circuit.h(0)
circuit.append(placeholder, [0], [0])
circuit.x(1)

print(circuit)
print(circuit.decompose()) # FAILS

```

### What should happen?

The decomposition pass should not fail, and behave the same as if multiple instructions would have been put into the placeholder. (See example when uncomment line 5)


### Any suggestions?

As far as I see it, the problem arises because of [this if-statement](https://github.com/Qiskit/qiskit-terra/blob/93e2fc52f98246c84b3079e1655ab2e44d943749/qiskit/transpiler/passes/basis/decompose.py#L94) in the decomposition pass:

```python
rule = node.op.definition.data
if len(rule) == 1 and len(node.qargs) == len(rule[0].qubits) == 1:
    if node.op.definition.global_phase:
        dag.global_phase += node.op.definition.global_phase
    dag.substitute_node(node, rule[0].operation, inplace=True)
```

This maybe seems to be a optimization (?) that can quickly handle a single-qubit instruction. However, I think it does not handle the case when the instruction does not have the same amount of clbits as the placeholder.


The simplest fix would be to omit the if statement, and execute the else-statement
```python
else:
    decomposition = circuit_to_dag(node.op.definition)
    dag.substitute_node_with_dag(node, decomposition)
```

in any case.

Pull request:
Fix decomposition of an instruction with a single qubit and clbit
<!--
⚠️ If you do not respect this template, your pull request will be closed.
⚠️ Your pull request title should be short detailed and understandable for all.
⚠️ Also, please add a release note file using reno if the change needs to be
  documented in the release notes.
⚠️ If your pull request fixes an open issue, please link to the issue.

- [ ] I have added the tests to cover my changes.
- [ ] I have updated the documentation accordingly.
- [ ] I have read the CONTRIBUTING document.
-->

### Summary

Fixes #8591.

### Details and comments

Added a check to ensure the node that is replaced has the same number of classical bits that the rule we replace it with. Both these are required to be 0 right now as we don't have any gates that contain classical bits. I think this number could be allowed to be <= 1 though -- more than 1 would not necesssarily preserve the order?


Patch:
diff --git a/qiskit/transpiler/passes/basis/decompose.py b/qiskit/transpiler/passes/basis/decompose.py
index 408a95271..062e97558 100644
--- a/qiskit/transpiler/passes/basis/decompose.py
+++ b/qiskit/transpiler/passes/basis/decompose.py
@@ -91,7 +91,11 @@ class Decompose(TransformationPass):
                     continue
                 # TODO: allow choosing among multiple decomposition rules
                 rule = node.op.definition.data
-                if len(rule) == 1 and len(node.qargs) == len(rule[0].qubits) == 1:
+                if (
+                    len(rule) == 1
+                    and len(node.qargs) == len(rule[0].qubits) == 1  # to preserve gate order
+                    and len(node.cargs) == len(rule[0].clbits) == 0
+                ):
                     if node.op.definition.global_phase:
                         dag.global_phase += node.op.definition.global_phase
                     dag.substitute_node(node, rule[0].operation, inplace=True)
diff --git a/releasenotes/notes/fix-decomp-1q-1c-84f369f9a897a5b7.yaml b/releasenotes/notes/fix-decomp-1q-1c-84f369f9a897a5b7.yaml
new file mode 100644
index 000000000..74d8d1faa
--- /dev/null
+++ b/releasenotes/notes/fix-decomp-1q-1c-84f369f9a897a5b7.yaml
@@ -0,0 +1,13 @@
+---
+fixes:
+  - |
+    Fixed a bug where decomposing an instruction with one qubit and one classical bit 
+    containing a single quantum gate failed. Now the following decomposes as expected::
+
+        block = QuantumCircuit(1, 1)
+        block.h(0)
+
+        circuit = QuantumCircuit(1, 1)
+        circuit.append(block, [0], [0])
+
+        decomposed = circuit.decompose()


Test patch:
diff --git a/test/python/transpiler/test_decompose.py b/test/python/transpiler/test_decompose.py
index 1a0aaf4a4..2664a00c7 100644
--- a/test/python/transpiler/test_decompose.py
+++ b/test/python/transpiler/test_decompose.py
@@ -300,3 +300,18 @@ class TestDecompose(QiskitTestCase):
         decom_circ = self.complex_circuit.decompose(reps=2)
         decomposed = self.complex_circuit.decompose().decompose()
         self.assertEqual(decom_circ, decomposed)
+
+    def test_decompose_single_qubit_clbit(self):
+        """Test the decomposition of a block with a single qubit and clbit works.
+
+        Regression test of Qiskit/qiskit-terra#8591.
+        """
+        block = QuantumCircuit(1, 1)
+        block.h(0)
+
+        circuit = QuantumCircuit(1, 1)
+        circuit.append(block, [0], [0])
+
+        decomposed = circuit.decompose()
+
+        self.assertEqual(decomposed, block)