Skip to content

[BUG] Function overloading with an @enum type produces unexpected results #687

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

Closed
guybrush77 opened this issue Sep 17, 2023 · 9 comments
Closed
Labels
bug Something isn't working

Comments

@guybrush77
Copy link

Describe the bug

Function overloading with an @enum type produces unexpected results.

To Reproduce

Try the following code:

Color: @enum type = {
    RED;
    GREEN;
    BLUE;
}

foo: (color: Color) = {
    std::cout << "Invoked foo: (color: Color)\n";
}

foo: (color: _) = {
    std::cout << "Invoked foo: (color: _)\n";
}

main: () = {
    foo(Color::RED);
}

After running this program, I'd expect to see the following on stdout:

Invoked foo: (color: Color)

Instead, the generic function is called:

Invoked foo: (color: _)
@guybrush77 guybrush77 added the bug Something isn't working label Sep 17, 2023
@JohelEGP
Copy link
Contributor

This was hinted at #131 (comment).

@JohelEGP
Copy link
Contributor

This formulation seems to permit having seemingly static constexpr data members of the type being defined (https://compiler-explorer.com/z/7nY47a7YG):

struct perms {
  unsigned underlying;

  static const perms read;
};

constexpr perms perms::read = {1};

static_assert(perms::read.underlying == 1);

#include <type_traits>

static_assert(std::integral_constant<perms, perms::read>{}.value.underlying == 1);

@guybrush77
Copy link
Author

Thanks, I understand the underlying issue now.

Still, I hope that the ergonomics can be improved. I think the new @enum fails to adhere to the principle of least astonishment.

@JohelEGP
Copy link
Contributor

JohelEGP commented Sep 19, 2023

Emitting object aliases at type-scope like above at #687 (comment)
makes it possible for @enum and @flag_enum to have enumerators of the type of the enumeration.

But it would also makes all other uses of them in the signatures of members impossible.
Which I think is a much more common use case than having static data members of equal type.
For example, see ref-is-glvalue at https://eel.is/c++draft/range.join.iterator.

@guybrush77
Copy link
Author

Right. I agree that using enums in signatures is a desirable feature.

Anyway, I will close this bug since it is not really a bug, but more like a design tradeoff.

@JohelEGP
Copy link
Contributor

I view it as a bug that the enumerator doesn't have the type of the enumeration.
I think using functions to return the enumerator values would be better.
A Cpp1 enumerator is a platonic value.
A Cpp2 enumerator is an object alias.
But if Cpp2 enumerators were returned by a function,
they'd once again become platonic values.

@JohelEGP
Copy link
Contributor

Although there'd be more resistance to migrating to Cpp2's @enum from Cpp1's enum if you had to call enumerators to get the value.
And there's the chance of using the function pointer accidentally
(and ah, we'd have function(s) (pointers) in addition to the platonic values).
Perhaps it'd be better if Cpp2 simply treated type-scope object aliases with type equal to the type being defined specially
and they were lowered like #687 (comment).
Then we can all live happily.

@hsutter
Copy link
Owner

hsutter commented Sep 19, 2023

Ack: Yes, I'm looking at this now. I always intended for enumerators to have the type of the enumeration, but Cpp1 doesn't allow that, so the initial implementation worked around it.

The solution I'm currently pursuing is to lower all type-scope object aliases as you suggest (see also https://stackoverflow.com/questions/11928089/), and then enumerators would Just Work too. That way I don't need to make enumerations a special case.

@hsutter
Copy link
Owner

hsutter commented Sep 22, 2023

I've now improved this in b589f5d

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants