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

"Error: Type error. Expecting an integral type" error when assigning an enum value with a constexpr with 4.2.0, while generation is correct with 4.1.1 #2783

Closed
traversaro opened this issue Jan 30, 2024 · 5 comments

Comments

@traversaro
Copy link

traversaro commented Jan 30, 2024

If I try to wrap with SWIG a C++ enum whose value is assigned by a constexpr function, the generation fails with:

./testswig.i:11: Error: Type error. Expecting an integral type

error.

Minimum Reproducible Example

If you create a testswig.i file with content (I know that the resulting generated code would not work, I just tried to keep the example file as small as possible):

%module testmod

constexpr int getOne()
{
    return 1;
}

enum TestEnum
{
    VAL0 = 0,
    VAL1 = getOne(),
};

and compile it with:

swig -python -c++  ./testswig.i

in swig <= 4.1.1 everything works fine, while in swig==4.2.0 one gets the error:

./testswig.i:11: Error: Type error. Expecting an integral type
@traversaro traversaro changed the title "Error: Type error. Expecting an integral type" error when assigning an enum value with a constexpr "Error: Type error. Expecting an integral type" error when assigning an enum value with a constexpr with 4.2.0, while generation is correct with 4.1.1 Jan 30, 2024
@ojwb
Copy link
Member

ojwb commented Jan 30, 2024

Ironically this is due to the improvements in type deduction in .4.2.0 - the internal typecode for the expression getOne() is now T_USER whereas before it was T_INT. T_INT is actually correct, however it was right for the wrong reason before (essentially the parser assigned code T_INT as a sort of default when it didn't actually know the code, but we need to distinguish that case from the case where we actually know it's int to reliably deduce types).

T_USER is also wrong though (that means e.g. class Foo) - really it should either be T_INT (if SWIG can deduce the type in this case) or T_UNKNOWN (if it can't). I would expect it to be able to deduce this case.

git bisect shows this as introduced by b5ca500 which is about deducing the type of things like double(4) which is odd as I don't see anything which seems like it could parse like that here. Reverting that commit locally fixes the error, so it seems it is indeed this change at fault.

I'll investigate. This change could just be reverted for 4.2.1 if I don't get to the bottom of this before then.

@traversaro
Copy link
Author

Thanks a lot @ojwb !

@ojwb
Copy link
Member

ojwb commented Jan 30, 2024

Thanks for the great reproducer!

I've worked out the reason this grammar rule fires at least - it's what parses getOne().

@ojwb ojwb closed this as completed in d6850a6 Jan 30, 2024
@ojwb
Copy link
Member

ojwb commented Jan 30, 2024

Fixed.

I would expect it to be able to deduce this case.

Actually we don't currently deduce the return type of a function call - it's more complicated than it might initially seem as it can vary between overloaded forms, consider:

int getOne(int x) { return x + 1; }
short getOne(short x) { return x + 1; }

Here we need to look at the types of the parameters passed in a call like getOne(x) to correctly deduce the return type. It's possible but not trivial.

We could probably handle the case where there's no overloading (or where there is but the return type is always the same) more easily.

@traversaro
Copy link
Author

Thanks a lot @ojwb ! Indeed I just tested and your change also fixes the real world code base from which I extracted the reproducer, for reference:

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