Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Fix: core.stdcpp.vector cannot have core.stdcpp.vector as element #3238

Merged
merged 1 commit into from
Oct 25, 2020

Conversation

n8sh
Copy link
Member

@n8sh n8sh commented Oct 17, 2020

Only pertains to 64-bit Windows since that's the only platform currently supported by core.stdcpp.vector.

@dlang-bot
Copy link
Contributor

Thanks for your pull request, @n8sh!

Bugzilla references

Auto-close Bugzilla Severity Description
21323 normal (64-bit Windows only) core.stdcpp.vector could not have core.stdcpp.vector as element

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "stable + druntime#3238"

@dlang-bot dlang-bot added the Bug Fix Include reference to corresponding bugzilla issue label Oct 17, 2020
@@ -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]);
Copy link
Contributor

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...

Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Contributor

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 :/

Copy link
Member Author

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.

Copy link
Contributor

@TurkeyMan TurkeyMan left a 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?

@n8sh
Copy link
Member Author

n8sh commented Oct 17, 2020

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 vector privately imports moveEmplace andvector.moveEmplace is visible to the other vector.

@thewilsonator
Copy link
Contributor

git clone -b v2.094.1 --depth=1 https://github.com/dlang/druntime .generated/druntime-2.094.1
Cloning into '.generated/druntime-2.094.1'...
warning: Could not find remote branch v2.094.1 to clone.
fatal: Remote branch v2.094.1 not found in upstream origin

This is probably due to the issues merging stable.

@TurkeyMan
Copy link
Contributor

The specific issue here is that vector privately imports moveEmplace andvector.moveEmplace is visible to the other vector.

That is clearly the issue here... an API should not be designed to not work with UFCS.
This fix should instead use a renaming import when importing moveEmplace, or change the location of the import so this can't occur.
This issue you demonstrate here actually suggests to me that it might be general bad practise to use local imports in struct/class scopes, because it may interfere with UFCS in a surprising and undesirable way. I hadn't encountered this issue before, but I think it will necessitate my choosing to not ever import into public struct scope in the future.

Copy link
Contributor

@TurkeyMan TurkeyMan left a 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]);
Copy link
Contributor

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.

@n8sh
Copy link
Member Author

n8sh commented Oct 19, 2020

maybe they could be private? (not sure if making them private would actually solve the issue?)

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.

@@ -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;
Copy link
Contributor

@TurkeyMan TurkeyMan Oct 20, 2020

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?

Copy link
Member Author

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.

Copy link
Contributor

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.

Copy link
Contributor

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.

@12345swordy
Copy link
Contributor

All good to go?

@TurkeyMan
Copy link
Contributor

Do it

@dlang-bot dlang-bot merged commit 444fc36 into dlang:stable Oct 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Fix Include reference to corresponding bugzilla issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants