Repository: Qiskit/qiskit

Issue:
error adding custom instruction to circuit
reported by @chunfuchen:

```python
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
qr = QuantumRegister(2)
cr = ClassicalRegister(2)
qc = QuantumCircuit(qr, cr, name='inst')

qc.x(qr[0])
qc.h(qr[1])
qc.measure(qr[0], cr[0])
qc.measure(qr[1], cr[1])

inst = qc.to_instruction()
qc = QuantumCircuit(qr, cr, name='inst2')
qc.append(inst, qr[:], cr[:])
```
```
>> TypeError: unhashable type: 'list'
```


Discussion:

Resolving patch:
diff --git a/qiskit/circuit/instruction.py b/qiskit/circuit/instruction.py
--- a/qiskit/circuit/instruction.py
+++ b/qiskit/circuit/instruction.py
@@ -290,12 +290,7 @@ def qasm(self):
 
     def broadcast_arguments(self, qargs, cargs):
         """
-        Validation and handling of the arguments and its relationship. For example:
-        `cx([q[0],q[1]], q[2])` means `cx(q[0], q[2]); cx(q[1], q[2])`. This method
-        yields the arguments in the right grouping. In the example:
-           in: [[q[0],q[1]], q[2]],[]
-         outs: [q[0], q[2]], []
-               [q[1], q[2]], []
+        Validation of the arguments.
 
         Args:
             qargs (List): List of quantum bit arguments.
@@ -312,22 +307,7 @@ def broadcast_arguments(self, qargs, cargs):
             raise QiskitError(
                 'The amount of qubit arguments does not match the instruction expectation.')
 
-        if len(cargs) != self.num_clbits:
-            raise QiskitError(
-                'The amount of clbit arguments does not match the instruction expectation.')
-
-        if len(cargs) == len(qargs):
-            #  [[q[0], q[1]], [c[0], c[1]]] -> [q[0]], [r[0]]
-            #                               -> [q[1]], [r[1]]
-            for qarg, carg in zip(qargs, cargs):
-                yield [qarg], [carg]
-        elif not cargs and len(qargs) == 1:
-            #  [[q[0], q[1]], []] -> [q[0]], []]
-            #                     -> [q[1]], []
-            for qarg in qargs[0]:
-                yield [qarg], []
-        else:
-            #  [[q[0], q[1]], [c[0], c[1]]] -> [q[0], r[0]], [q[1], r[1]]
-            flat_qargs = [qarg for sublist in qargs for qarg in sublist]
-            flat_cargs = [carg for sublist in cargs for carg in sublist]
-            yield flat_qargs, flat_cargs
+        #  [[q[0], q[1]], [c[0], c[1]]] -> [q[0], c[0]], [q[1], c[1]]
+        flat_qargs = [qarg for sublist in qargs for qarg in sublist]
+        flat_cargs = [carg for sublist in cargs for carg in sublist]
+        yield flat_qargs, flat_cargs


Test patch:
diff --git a/test/python/circuit/test_instructions.py b/test/python/circuit/test_instructions.py
--- a/test/python/circuit/test_instructions.py
+++ b/test/python/circuit/test_instructions.py
@@ -249,6 +249,26 @@ def test_inverse_opaque(self):
         opaque_gate = Gate(name='crz_2', num_qubits=2, params=[0.5])
         self.assertRaises(QiskitError, opaque_gate.inverse)
 
+    def test_no_broadcast(self):
+        """See https://github.com/Qiskit/qiskit-terra/issues/2777
+        When creating custom instructions, do not broadcast parameters"""
+        qr = QuantumRegister(2)
+        cr = ClassicalRegister(2)
+        subcircuit = QuantumCircuit(qr, cr, name='subcircuit')
+
+        subcircuit.x(qr[0])
+        subcircuit.h(qr[1])
+        subcircuit.measure(qr[0], cr[0])
+        subcircuit.measure(qr[1], cr[1])
+
+        inst = subcircuit.to_instruction()
+        circuit = QuantumCircuit(qr, cr, name='circuit')
+        circuit.append(inst, qr[:], cr[:])
+        self.assertEqual(circuit.qregs, [qr])
+        self.assertEqual(circuit.cregs, [cr])
+        self.assertEqual(circuit.qubits, [qr[0], qr[1]])
+        self.assertEqual(circuit.clbits, [cr[0], cr[1]])
+
 
 if __name__ == '__main__':
     unittest.main()