[Question] Lowering memref<?xi8> to EmitC difficulty

I have a toy language called Rice that I want to compile to C through MLIR. I’m representing strings as memref<?xi8> and I’m having trouble lowering my rice.print operator to EmitC with the following “Hello World” program:

module {
  memref.global constant @str_0 : memref<12xi8> = dense<[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]>
  func.func @main() {
    %0 = memref.get_global @str_0 : memref<12xi8>
    %cast = memref.cast %0 : memref<12xi8> to memref<?xi8>
    "rice.print"(%cast) : (memref<?xi8>) -> ()
    %c0_i32 = arith.constant 0 : i32
    return
  }
}

My thought was that rice.print can simply get transformed into an emitc.call that calls puts (for more complete calls I want to use printf but for starters I’m testing with puts). Ideally this should get lowered into:

module {
    emitc.global extern const @str_0 : !emitc.array<12xi8> = dense<[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]>

    emitc.func private @puts(!emitc.ptr<i8>) -> i32 attributes {specifiers = ["extern"]}

    emitc.func @main() -> i32 {
      %0 = emitc.get_global @str_0 : !emitc.array<12xi8>
      %ptr = emitc.cast %0 : !emitc.array<12xi8> to !emitc.ptr<i8>
      %result = emitc.call @puts(%ptr) : (!emitc.ptr<i8>) -> i32
      %zero = "emitc.constant"() <{value = 0 : i32}> : () -> i32
      emitc.return %zero : i32
    }
  }

My dilemma is that EmitC doesn’t take memref<?xi8>, and the --convert-memref-to-emitc` rejects memref<?xi8>. My first naive lowering transforms rice.print into a func.call of the external function puts:

module {
  func.func private @puts(memref<?xi8>)

  memref.global constant @str_0 : memref<12xi8> = dense<[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]>

  func.func @main() {
    %0 = memref.get_global @str_0 : memref<12xi8>
    %cast = memref.cast %0 : memref<12xi8> to memref<?xi8>
    func.call @puts(%cast) : (memref<?xi8>) -> ()
    %c0_i32 = arith.constant 0 : i32
    return
  }
}

And mlir-opt is not happy with memref<?xi8>

> mlir-opt --convert-memref-to-emitc --convert-func-to-emitc test2.mlir
test2.mlir:8:13: error: failed to legalize operation 'memref.cast' that was explicitly marked illegal
    %cast = memref.cast %0 : memref<12xi8> to memref<?xi8>
            ^
test2.mlir:8:13: note: see current operation: %2 = "memref.cast"(%1) : (memref<12xi8>) -> memref<?xi8>

How should I deal with memref<?xi8> if I want to lower to EmitC? Should I be writing my own RiceAndMemRefToEmitCPass that mix n’ match the OpConversionPatterns defined in MemRefToEmitC.cpp plus my own pattern that converts memref.cast into a emitc.cast?