Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WARN: Skip unsupported call expression #948

Open
scovich opened this issue May 1, 2024 · 1 comment
Open

WARN: Skip unsupported call expression #948

scovich opened this issue May 1, 2024 · 1 comment

Comments

@scovich
Copy link
Contributor

scovich commented May 1, 2024

When generating FFI bindings for delta_kernel, the following construct:

pub enum PrimitiveType {
    Long,
}

pub enum DataType {
    Primitive(PrimitiveType),
}

impl DataType {
    pub const LONG: Self = DataType::Primitive(PrimitiveType::Long);
}

causes cbindgen to emit the following warning:

WARN: Skip delta_kernel::LONG - (Unsupported call expression. Call(... <snipped> ...))
Full warning text

(indented for readability)

WARN: Skip delta_kernel::LONG - (
  Unsupported call expression.
  Call(
    ExprCall {
      attrs: [],
      func: Path(
        ExprPath {
          attrs: [],
          qself: None,
          path: Path {
            leading_colon: None,
            segments: [
              PathSegment { ident: Ident(DataType), arguments: None },
              Colon2,
              PathSegment { ident: Ident(Primitive), arguments: None }
            ]
          }
        }
      ),
      paren_token: Paren,
      args: [
        Path(
          ExprPath {
            attrs: [],
            qself: None,
            path: Path {
              leading_colon: None,
              segments: [
                PathSegment { ident: Ident(PrimitiveType), arguments: None },
                Colon2,
                PathSegment { ident: Ident(Long), arguments: None }
              ]
            }
          }
        )
      ]
    }
  )
)

I suspect the problem is a shortcoming in the cbindgen parser, since the constant is ultimately just a nested struct initialization?

If I mark the types #[repr(C)] then cbindgen emits the following definitions for them:

enum class PrimitiveType {
  Long,
};

struct DataType {
  enum class Tag {
    Primitive,
  };

  struct Primitive_Body {
    PrimitiveType _0;
  };

  Tag tag;
  union {
    Primitive_Body primitive;
  };
};

... and the following constant initializer compiles fine with both gcc and clang:

constexpr static const DataType DataType_LONG = DataType {
    DataType::Tag::Primitive, 
    DataType::Primitive_Body { PrimitiveType::Long },
};

(cbindgen should be able to tell this isn't an arbitrary function call, after having parsed the corresponding types)

Note that the pub const which triggers the warning is NOT intended for FFI export by the delta_kernel_ffi crate. It is actually defined in a dependent crate (delta_kernel), and neither DataType nor Primitive is #[repr(C)]. In fact, the types are not even emitted because no FFI function references them (but apparently constants don't have to be referenced to be exported). Thus, the warning is annoying but harmless in this specific case (see #673)

Unfortunately, annotating the constant with /// cbindgen:no-export or /// cbindgen:ignore does NOT suppress the warning. Maybe that's a side effect of the fact that cbindgen does not seem to respect either annotation for constants in the first place (filed as #947)?

@emilio
Copy link
Collaborator

emilio commented May 7, 2024

Yeah, syntax-wise there's no way to know whether DataType::Primitive is a function or an enum initializer... So seems somewhat tricky to suppress this warning...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants