Repository: Qiskit/qiskit

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.


Discussion:

Resolving patch:
diff --git a/qiskit/transpiler/passes/basis/decompose.py b/qiskit/transpiler/passes/basis/decompose.py
--- a/qiskit/transpiler/passes/basis/decompose.py
+++ b/qiskit/transpiler/passes/basis/decompose.py
@@ -91,7 +91,11 @@ def run(self, dag: DAGCircuit) -> DAGCircuit:
                     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)


Test patch:
diff --git a/test/python/transpiler/test_decompose.py b/test/python/transpiler/test_decompose.py
--- a/test/python/transpiler/test_decompose.py
+++ b/test/python/transpiler/test_decompose.py
@@ -300,3 +300,18 @@ def test_decompose_reps(self):
         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)