-
-
Notifications
You must be signed in to change notification settings - Fork 706
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
Enable preview=fieldwise & fix blocking bug in VariantN #7622
Conversation
... with preview=fieldwise. Equality checks will never fail for instances of empty structs, hence don't generate code checking `<` and `>` for them. This was exposed by `-preview=fieldwise` which (as a side effect) enables dmd to const-fold the aformentioned equality test in the frontend.
|
Thanks for your pull request and interest in making D better, @MoonlightSentinel! 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
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + phobos#7622" |
|
Blocked because it won't compile without Guess we should finally have a way to silence the warning in generic code (because detecting that the code is unreachable is impossible/really akward here) |
| static if (is(typeof(*zis < *rhsPA))) | ||
| static if (is(A == struct) && A.init.tupleof.length == 0) | ||
| { | ||
| // The check above will always succeed if A is an empty struct. |
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.
Why not return 0; here?
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.
Because it would be unreachable code - diagnosed with -preview=fieldwise.
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.
What about moving
if (*rhsPA == *zis) { return 0; }as two separate code duplications into the else static if and else branches? I guess we can afford some code duplication here.
That should remove the warning for the
static if (is(A == struct) && A.init.tupleof.length == 0)case right?
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 compiles for me without the flag -preview=fieldwise:
static ptrdiff_t compare(A* rhsPA, A* zis, OpID selector)
{
static if (is(typeof(*rhsPA == *zis)))
{
enum isEmptyStruct = is(A == struct) && A.init.tupleof.length == 0;
static if (!isEmptyStruct)
{
if (*rhsPA == *zis)
return 0;
}
static if (isEmptyStruct)
{
return 0;
// The check above will always succeed if A is an empty struct.
// Don't generate unreachable code as seen in
// https://issues.dlang.org/show_bug.cgi?id=21231
}
else static if (is(typeof(*zis < *rhsPA)))
{
// Many types (such as any using the default Object opCmp)
// will throw on an invalid opCmp, so do it only
// if the caller requests it.
if (selector == OpID.compare)
return *zis < *rhsPA ? -1 : 1;
else
return ptrdiff_t.min;
}
else
{
// Not equal, and type does not support ordering
// comparisons.
return ptrdiff_t.min;
}
}
else
{
// Type does not support comparisons at all.
return ptrdiff_t.min;
}
}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.
That would also need to check for user-defined opEquals inside of an empty struct.
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.
The user-defined opEquals may have different semantics than the compiler generated one (e.g. return false
). Your proposal skips it and simply returns "equal".
Additionally, the warning disappears when the empty struct defines an opEquals (see https://run.dlang.io/is/rvo4Yt), which suggests that it breaks the early const-folding. That would trigger the missing return,... again
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.
The user-defined
opEqualsmay have different semantics than the compiler generated one (e.g.return false
). Your proposal skips it and simply returns "equal".
What about statically checking for presence of user-defined opEquals and avoid special handling then?
Have you asked @WalterBright how to proceed with these problems?
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.
What about statically checking for presence of user-defined
opEqualsand avoid special handling then?
That could work
Have you asked @WalterBright how to proceed with these problems?
No and I don't see a reason to do so. He rarely contributes to phobos and there's more imporant work only he can do (e.g. review backend pull requests)
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.
Ok, thanks.
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.
Yup, the bright side of the lack of leadership is that we have more decision freedom here than at DMD ;-)
How does this error? |
Missing |
I believe I have a solution. See code above. |
Nice. But i really think the compiler should ignore "unused code" for such scenarios. Trying to find an akward workaround wastes a lot of a developers time (and probably increases compilation time) for very little benefit. |
|
Are you putting this in another PR? |
|
I have an idea. Instead of disabling unreachable code analysis, what about making its diagnostics better in conveying to the developer how he should change the code to avoid the warning. For instance could instead say something like . I realize that there may be more complicated cases to describe than this, though. |
|
I hope it's ok that I reopen this. |
|
Well, better diagnostics for non-templated code would be nice indeed. But that doesn't help code where "unreachable" is dependent on template parameters (and somewhat on compiler flags). Also note that the compiler should only suppress "unreachable code" warnings when there is a conditionally compiled |
The first commit removes unreachable code in VaraintN for struct without members. This bug was exposed by
-preview=fieldwisewich enables early const-folding forEmptyStruct == EmptyStruct(alwaystrue).The second commit enables the flag for phobos s.t. it stays compatible in the future.