-
-
Notifications
You must be signed in to change notification settings - Fork 607
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
Fix Issues 19399 and 10560 - Different Conversion Rules for Same Value and Type Enum #10099
Conversation
Thanks for your pull request and interest in making D better, @RazvanN7! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla references
|
Phobos fix: dlang/phobos#7094 |
This should target stable |
This cannot target stable. It is silent change of code behavior; I thought about issuing a deprecation, but deprecations are issued for errors. |
Fair enough. |
src/dmd/dcast.d
Outdated
if (auto edType = e.type.isTypeEnum) | ||
{ | ||
auto ed = edType.sym; | ||
if (ed.hasUserDefinedType && m == MATCH.nomatch) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merge above two lines, no point to ed
variable.
src/dmd/denum.d
Outdated
@@ -65,6 +66,8 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol | |||
//printf("EnumDeclaration() %s\n", toChars()); | |||
type = new TypeEnum(this); | |||
this.memtype = memtype; | |||
if (memtype) | |||
hasUserDefinedType = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This introduces a very subtle bug. Take a look at the function getMemType(). If memtype is not provided, it is set to a default value. Now take a look at syntaxCopy(), which creates a new EnumDeclaration and passes memtype to it. But if memtype was set by getMemType(), it is not null, and hasUserDefinedType is incorrectly set to true.
The easiest way to fix this is have syntaxCopy() also copy hasUserDefinedType.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or more properly, make hasUserDefinedType a parameter to the constructor.
The referenced issues are not compiler bugs and are not language bugs. See explanations added to https://issues.dlang.org/show_bug.cgi?id=19399 |
Once the enum value has been analyzed and lowered to a literal expression, if the enum type cannot be implicitly converted to the desired type, VRP steps in and does the appropriate type modifications; this is problematic because it bypasses the type that the user has provided. To fix this, I added a check that disables VRP if the user provided type cannot be implicitly converted to the desired type; if no type is provided for the enum, the initial behavior is still in place (i.e. [1]).
[1] https://issues.dlang.org/show_bug.cgi?id=9999