-
-
Notifications
You must be signed in to change notification settings - Fork 421
Fix: core.stdcpp.vector cannot have core.stdcpp.vector as element #3238
Conversation
|
Thanks for your pull request, @n8sh! 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 "stable + druntime#3238" |
| @@ -587,7 +587,7 @@ extern(D): | |||
| for (size_t i = _Size; i > 0; ) | |||
| { | |||
| --i; | |||
| _Get_data()._Myfirst[i].moveEmplace(_Newvec[i]); | |||
| moveEmplace(_Get_data()._Myfirst[i], _Newvec[i]); | |||
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.
O_o ... what's going on here? If that fixes a bug, then I'm worried there's an issue with the language...
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.
Based on your recent comment, I think this fix is hiding the issue, and you should revert this change and fix the issue instead.
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 fix this specific case but a related problem could still arise for any struct with a public member named moveEmplace.
That might not be a problem. It could be a member function with a contract compatible with core.lifetime.moveEmplace which may have legitimate reason to exist and using it instead of the expected function could be beneficial. Against this I'll note that move and core_emplace aren't used inside vector with UFCS. That style was only used with that single call to moveEmplace.
Please confirm you have read this and still want to retain UFCS here. If so I will change the PR as requested.
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.
could still arise for any struct with a public member named
moveEmplace
Oh yeah, of course >_<
Perhaps both fixes are necessary... although it depends on if it's decided that creating a moveEmplace local to the object as a global override is a desired feature or not? Should it be considered that an object's local version is an intent to override the global? I think that needs to be resolved broadly.
Sadly, moveEmplace is a gross hack in D, and I'm not sure I would trust anyone to write it, but this pattern should should be decided and applied broadly.
I'm quite certain that it's improper for vector to have those local imports at member-scope, but the fix to this line can be seen from either perspective as you've shown :/
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.
Updated the PR to apply both fixes.
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.
LGTM... but why does this work? Is there a larger issue?
|
A similar problem would arise with UFCS for any type with a visible member with the same name as the function. The specific issue here is that |
This is probably due to the issues merging stable. |
That is clearly the issue here... an API should not be designed to not work with UFCS. |
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.
I think the imports should be moved to be function-local, or module scoped, or they could be renamed, or maybe they could be private? (not sure if making them private would actually solve the issue?)
| @@ -587,7 +587,7 @@ extern(D): | |||
| for (size_t i = _Size; i > 0; ) | |||
| { | |||
| --i; | |||
| _Get_data()._Myfirst[i].moveEmplace(_Newvec[i]); | |||
| moveEmplace(_Get_data()._Myfirst[i], _Newvec[i]); | |||
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.
Based on your recent comment, I think this fix is hiding the issue, and you should revert this change and fix the issue instead.
They are already private (that is now the default), the issue here being that vector!A can see the private imports of vector!B. In any file except core.stdcpp.vector.d there would be no problem using UFCS to call moveEmplace on a vector. |
…have core.stdcpp.vector as element
| @@ -32,7 +32,7 @@ extern(C++, "std"): | |||
|
|
|||
| extern(C++, class) struct vector(T, Alloc = allocator!T) | |||
| { | |||
| import core.lifetime : forward, move, moveEmplace, core_emplace = emplace; | |||
| import core.lifetime : forward, move, core_emplace = emplace; | |||
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.
I think it's likely that all of these will trigger the same problem... no?
auto newVector = myVector.move(); <- same issue?
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.
It works fine because UFCS isn't used for those inside vector and outside vector the imports aren't visible.
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.
How is it not visible? Those imports are public, and definitely visible.
import core.lifetime : move;
struct Test
{
import core.lifetime : move;
}
int main()
{
Test t;
auto u = move(t); <- works
auto v = t.move(); <- fails, because sees the local one, and thinks it has no arguments
return 0;
}Basically, when you import anything into struct/class scope, it seems to be preferred over UFCS.
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.
Oh I see, you're saying the imports are private by default. My test is within a module.
Yeah, fair enough, but the whole thing kinda smells to me :/
The same problems may occur within a module, but less likely, and at least you can control the situation in that case.
|
All good to go? |
|
Do it |
Only pertains to 64-bit Windows since that's the only platform currently supported by core.stdcpp.vector.