Error: expected type <type>, found <same-type>

Hi!,

I am learning zig. I keep getting this problem where
the compiler errors saying that the expected type doesn’t match the
found type. And they are the same visually.

notes:

  • In this case the type is coming from a cImport.
  • The error only happens when two files import the same C header.

If I copy the offending function into the same file that calls it
the error goes away. (Meaning they calling type and and the function
definition type are using the same cImport.)

I am assuming then that my error is that the cImport like is not
being “shared” be re-compiled into it’s own namespace each time.
(I am speaking loosely there.)

Is there some idiomatioc way to deal with this?
Maybe I should only cImport once into a zig namespace, and
then distribute from there?

Do you have multiple @cImport statements?

Unless you provide code and at least a minimal reproduction it’s going to be difficult to help you.

2 Likes
  1. Ensure that all the related cInclude are in one cImport.
  2. Ensure that you only cImport once. The trick is to reuse the cImport declaration by making it pub.
5 Likes

Thanks both!

That confirms my suspicion.

Yes I have the same cImports(s) in two zig files.

I think I need to have cImport once, and then share it
from there a in a more zig native way. Like making the
resulting import var pub.

2 Likes
//root.zig
      1 const std = @import("std");
      2 const page = @import("page.zig");
      3 const print = std.debug.print;
      4 pub const fcgi = @cImport({
      5     @cInclude("fcgiapp.h");
      6 });
      7     
      8 fn mainloop(r: *fcgi.FCGX_Request) void {
      9     while (fcgi.FCGX_Accept_r(r) == 0) {
     10         page.page1(r);
     11         fcgi.FCGX_Finish_r(r);
     12     }
     13 }
     14  
  

//page.zig
      1 const std = @import("std");
      2 const fcgi = @import("root.zig").fcgi;
      3 
      4 pub fn page1(r: *fcgi.FCGX_Request) void {
      5     _ = fcgi.FCGX_FPrintF(r.*.out, "Content-type: text/html\r\n\r\n");
      6     _ = fcgi.FCGX_FPrintF(r.*.out, "<!DOCTYPE HTML>\n");
       ....

This fixes it :). And I think I understand it better now.

Previously I had that same fcgi import that is in the first file root.zig
also in page.zig.

Now I import it once in root.zig and make it pub. And then
in page.zig I get it like line 2. So it’s the “same” fcgi not two of them that
look the same.

2 Likes

FWIW cimport is slated for removal with the build system’s translate c being preferred (c import was just language level support for this).

Using translate c directly sidesteps this issue, as you will get one module you can import anywhere. On the other hand, cimport creates a new translate c each time even if the result is identical.

It’s literally the same as, in zig, defining two identical types in separate files, then trying to use them interchangeably across your project.

I think it’s a caching issue that causes cimport to not only generate a new file each time even if they are duplicate, and make a module out of each of them. It could be solved to just work, or a half-baked solution could at least throw an error of a file being in multiple modules in the same import tree (that is a real zig error).
But solving that is moot due to the above deprecation, which will make it far less likely to encounter.

3 Likes

Thanks!,
I see this so I will investigate using translate-c:

I also see this:

This seems to say that multiple cImports should cause it
to be cached and re-used? But I also see it may be moot :slight_smile:

I was able to use translate-c and generate a zig file.
Which I could then just regular @import wherever I wanted.
(meaining I didn’t have to worry about just importing
it once and sharing it from there like I needed with @cImport.

:slight_smile:

I like this I have it in my Makefile to generate the file, and
it’s very seemless.

You don’t need to bother with make, just use addTranslateC from your build.zig, here is an example:

3 Likes

Thanks, this looks good. :slight_smile:

1 Like