EDSC: properly construct FunctionTypes

The existing implementation of makeFunctionType in EDSC contains a bug: the
array of input types is overwritten using output types passed as arguments and
the array of output types is never filled in.  This leads to all sorts of
incorrect memory behavior.  Fill in the array of output types using the proper
argument.

PiperOrigin-RevId: 234177221
diff --git a/bindings/python/test/test_py2and3.py b/bindings/python/test/test_py2and3.py
index 3b021cd..2f9b0cf 100644
--- a/bindings/python/test/test_py2and3.py
+++ b/bindings/python/test/test_py2and3.py
@@ -147,6 +147,9 @@
         "func @copy(%arg0: memref<3x4x?x5xf32>, %arg1: memref<3x4x?x5xf32>) {",
         f.__str__())
 
+    f = module.make_function("sqrtf", [t], [t])
+    self.assertIn("func @sqrtf(%arg0: f32) -> f32", f.__str__())
+
   def testMLIRConstantEmission(self):
     module = E.MLIRModule()
     f = module.make_function("constants", [], [])
diff --git a/lib/EDSC/Types.cpp b/lib/EDSC/Types.cpp
index 166715a..27f69a2 100644
--- a/lib/EDSC/Types.cpp
+++ b/lib/EDSC/Types.cpp
@@ -634,7 +634,7 @@
     ins[i] = mlir::Type::getFromOpaquePointer(inputs.types[i]);
   }
   for (unsigned i = 0; i < outputs.n; ++i) {
-    ins[i] = mlir::Type::getFromOpaquePointer(outputs.types[i]);
+    outs[i] = mlir::Type::getFromOpaquePointer(outputs.types[i]);
   }
   auto ft = mlir::FunctionType::get(
       ins, outs, reinterpret_cast<mlir::MLIRContext *>(context));