Skip to content
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

Make std.typecons.Tuple betterC compatible #5952

Merged
merged 2 commits into from
Dec 31, 2018
Merged

Conversation

wilzbach
Copy link
Member

@wilzbach wilzbach commented Dec 21, 2017

I'm not sure how people want to start testing -betterC compatibility with Phobos. I assume the best way would be to do extract all unittests marked with @betterC?

unittest @betterC
{
....
}

For now I went with a more simple and straight-forward way of simply executing all files in test/betterC.


Also I need to define `main` manually as the default main with `void main` returns with `44` :/

@wilzbach wilzbach added the Review:WIP Work In Progress - not ready for review or pulling label Dec 21, 2017
@dlang-bot
Copy link
Contributor

dlang-bot commented Dec 21, 2017

Thanks for your pull request, @wilzbach!

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

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

dub fetch digger
dub run digger -- build "master + phobos#5952"

posix.mak Outdated
test/betterC/%.run: test/betterC/%.d $(DMD) $(LIB)
mkdir -p $(ROOT)/unittest/betterC
$(DMD) $(DFLAGS) -of$(ROOT)/unittest/betterC/$(notdir $(basename $<)) -betterC $(UDFLAGS) $(LIB) \
-defaultlib= -debuglib= $(LINKDL) $<
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-betterC implies that we're not linking druntime and phobos -> drop $(LIB). This should hopefully get rid of the current linker error, though we get a new one.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hehe I thought so too and I tried this in the beginning, but then I get more linker errors:

generated/linux/release/64/unittest/betterC/test18101.o:test/betterC/test18101.d:function _D3std8typecons__T5TupleTiVAyaa6_736368656d61Z17injectNamedFieldsFZQBo: error: undefined reference to '_D12TypeInfo_Aya6__initZ'
generated/linux/release/64/unittest/betterC/test18101.o:test/betterC/test18101.d:function _D3std8typecons__T5TupleTiVAyaa6_736368656d61Z17injectNamedFieldsFZQBo: error: undefined reference to '_d_arraycatnTX'
generated/linux/release/64/unittest/betterC/test18101.o:test/betterC/test18101.d:function _D3std8typecons__T5TupleTiVAyaa6_736368656d61Z17injectNamedFieldsFZQBo: error: undefined reference to '_D12TypeInfo_Aya6__initZ'
generated/linux/release/64/unittest/betterC/test18101.o:test/betterC/test18101.d:function _D3std8typecons__T5TupleTiVAyaa6_736368656d61Z17injectNamedFieldsFZQBo: error: undefined reference to '_d_arrayappendT'
generated/linux/release/64/unittest/betterC/test18101.o:test/betterC/test18101.d:function _D3std8typecons__T5TupleTiVAyaa6_736368656d61Z17injectNamedFieldsFZQBo: error: undefined reference to '_D12TypeInfo_Aya6__initZ'
generated/linux/release/64/unittest/betterC/test18101.o:test/betterC/test18101.d:function _D3std8typecons__T5TupleTiVAyaa6_736368656d61Z17injectNamedFieldsFZQBo: error: undefined reference to '_d_arraycatnTX'
generated/linux/release/64/unittest/betterC/test18101.o:test/betterC/test18101.d:function _D3std8typecons__T5TupleTiVAyaa6_736368656d61Z17injectNamedFieldsFZQBo: error: undefined reference to '_D12TypeInfo_Aya6__initZ'
generated/linux/release/64/unittest/betterC/test18101.o:test/betterC/test18101.d:function _D3std8typecons__T5TupleTiVAyaa6_736368656d61Z17injectNamedFieldsFZQBo: error: undefined reference to '_d_arrayappendT'
generated/linux/release/64/unittest/betterC/test18101.o:test/betterC/test18101.d:function _D3std8typecons__T5TupleTiZ17injectNamedFieldsFZAya: error: undefined reference to '_d_arraycatnTX'
generated/linux/release/64/unittest/betterC/test18101.o:test/betterC/test18101.d:function _D3std8typecons__T5TupleTiZ17injectNamedFieldsFZAya: error: undefined reference to '_d_arrayappendT'
generated/linux/release/64/unittest/betterC/test18101.o:test/betterC/test18101.d:function _D3std8typecons__T5TupleTiVAyaa6_736368656d61ZQBc6toHashMxFNbNeZm: error: undefined reference to '_D10TypeInfo_i6__initZ'
generated/linux/release/64/unittest/betterC/test18101.o:test/betterC/test18101.d:function _D3std8typecons__T5TupleTiZQj6toHashMxFNbNeZm: error: undefined reference to '_D10TypeInfo_i6__initZ'
collect2: error: ld returned 1 exit status

Copy link
Member

@PetarKirov PetarKirov Dec 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two culprits here:

  1. injectNamedFields gets codegened -> we need to make sure that it exist only in CTFE context. One way to do this is to implement it as enum injectNamedFields = { /* code */ }();
  1. toHash uses typeid(T).getHash -> try replacing this with some template function which will get codegen-ed on demand (so that we don't need to linking druntime). You can try using core.internal.hash : hashOf, or if that doesn't work, we can workaround it temporary with:
version (D_BetterC)
    static assert (0, "Not implemented");
else:
    /* same as before ... */

and making Tuple.toHash a parameter-less template.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worked like a charm. Thanks!

@wilzbach wilzbach requested a review from MetaLang as a code owner December 22, 2017 11:34
wilzbach added a commit to wilzbach/phobos that referenced this pull request Dec 22, 2017
TypeInfo is part of DRuntime.
See: dlang#5952
wilzbach added a commit to wilzbach/phobos that referenced this pull request Dec 22, 2017
TypeInfo is part of DRuntime.
See: dlang#5952

Replaced `toHash` with a parameter-less template for codegen on demand.
@wilzbach wilzbach removed the Review:WIP Work In Progress - not ready for review or pulling label Dec 22, 2017
wilzbach added a commit to wilzbach/phobos that referenced this pull request Dec 22, 2017
TypeInfo is part of DRuntime.
See: dlang#5952

Replaced `toHash` with a parameter-less template for codegen on demand.
std/typecons.d Outdated
@@ -1135,12 +1135,20 @@ if (distinctFieldNames!(Specs))
Returns:
A `size_t` representing the hash of this `Tuple`.
*/
size_t toHash() const nothrow @trusted
size_t toHash()() const nothrow @trusted
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like why can't change this to a template:

std/functional.d(1003): Error: AA key type Tuple should have 'size_t toHash() const nothrow @safe' if opEquals defined
generated/linux/debug/64/publictests/std_functional.d(193): Error: template instance std_functional.__unittest_generated_linux_debug_64_publictests_std_functional_d_187_15.memoize!(fib) error instantiating
std/functional.d(1003): Error: AA key type Tuple should have 'size_t toHash() const nothrow @safe' if opEquals defined
generated/linux/debug/64/publictests/std_functional.d(205): Error: template instance std_functional.__unittest_generated_linux_debug_64_publictests_std_functional_d_199_16.memoize!(fact) error instantiating
std/functional.d(1003): Error: AA key type Tuple should have 'size_t toHash() const nothrow @safe' if opEquals defined
generated/linux/debug/64/publictests/std_functional.d(219): Error: template instance std_functional.__unittest_generated_linux_debug_64_publictests_std_functional_d_211_17.memoize!(factImpl) error instantiating

How about simply removing the method for betterC for now?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this:

size_t toHash() const nothrow @trusted
{
    version(D_BetterC)
    {
        // Disabled in -betterC for now as TypeInfo isn't present
        assert(0, "Not implemented");
    }
    else
    {
        size_t h = 0;
        foreach (i, T; Types)
            h += typeid(T).getHash(cast(const void*)&field[i]);
        return h;
    }
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would fail at runtime which is strictly worse then compile-time failure.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, that's why my first suggestion was to make toHash a template function and use static assert. Thinking about it more I don't see why we define our own opEquals and toHash, instead of relying on the compiler generated ones.

wilzbach added a commit to wilzbach/phobos that referenced this pull request Jan 19, 2018
TypeInfo is part of DRuntime.
See: dlang#5952

Replaced `toHash` with a parameter-less template for codegen on demand.
wilzbach added a commit to wilzbach/phobos that referenced this pull request Jul 19, 2018
TypeInfo is part of DRuntime.
See: dlang#5952

Replaced `toHash` with a parameter-less template for codegen on demand.
wilzbach added a commit to wilzbach/phobos that referenced this pull request Jul 19, 2018
TypeInfo is part of DRuntime.
See: dlang#5952

Replaced `toHash` with a parameter-less template for codegen on demand.
wilzbach added a commit to wilzbach/phobos that referenced this pull request Jul 19, 2018
TypeInfo is part of DRuntime.
See: dlang#5952

Replaced `toHash` with a parameter-less template for codegen on demand.
@wilzbach wilzbach changed the title [RFC] Add -betterC testsuite for Phobos Add -betterC testsuite for Phobos Jul 19, 2018
@wilzbach
Copy link
Member Author

Finally got around rebasing this. It looks like we can get around the problems of the static assert errors if we use the user-facing hashOf implementation.

Copy link
Member

@PetarKirov PetarKirov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm glad to see that this finally working!

std/typecons.d Outdated
{
size_t h = 0;
static foreach (i, T; Types)
{{
const k = typeid(T).getHash((() @trusted => cast(const void*) &field[i])());
const k = hashOf(field[i]);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, looks like hashOf can't handle void[] arrays:

/var/lib/jenkins/dlang_projects@4/distribution/bin/../imports/core/internal/hash.d(218,30): Error: template instance `core.internal.hash.hashOf!(const(void[32]))` error instantiating
/var/lib/jenkins/dlang_projects@4/distribution/bin/../imports/std/typecons.d(1177,33):        instantiated from here: `hashOf!(const(Json))`
/var/lib/jenkins/dlang_projects@4/distribution/bin/../imports/std/typecons.d(640,23):        instantiated from here: `Tuple!(string, Json)`

@n8sh as you have worked a lot on hashOf, maybe you have a good idea on how to fix this?
Can we cast void arrays to ubyte for hashing?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wilzbach hashOf void arrays is currently working in druntime master.

@wilzbach
Copy link
Member Author

Opened a separate PR that just adds the testsuite (#6640), s.t. we can already add the betterC testsuite.

wilzbach added a commit to wilzbach/phobos that referenced this pull request Aug 14, 2018
TypeInfo is part of DRuntime.
See: dlang#5952

Replaced `toHash` with a parameter-less template for codegen on demand.
@wilzbach wilzbach changed the title Add -betterC testsuite for Phobos Make std.typecons.Tuple betterC compatible Aug 14, 2018
@wilzbach
Copy link
Member Author

Well, we can't use Tuple!(int, Json) yet, but thanks to a few recent changes in druntime this seems to be finally passing.
I added a very simplistic -betterC test in the test/betterc testsuite, but once we finally get @betterC I plan on annotating a few unittests, s.t. we can ensure Tuple will continue to work in -betterC.

@@ -0,0 +1,7 @@
extern(C) void main()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you now move it inside std.typecons as a @BetterC unittest?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can/will do this once #6645 has been merged.

@n8sh
Copy link
Member

n8sh commented Aug 16, 2018

Unfortunately, core.internal.hashOf is not wholly betterC compatible because of hashOf's need to produce bitwise representations of structs in CTFE. The various core.internal.convert.toUbyte overloads have allocation with new in their CTFE-only paths.

@PetarKirov
Copy link
Member

@n8sh the enum function trick used in this PR may help for hashOf's use of CTFE. (Though of course the compiler should also be fixed.)

std/typecons.d Outdated
@@ -1168,12 +1168,12 @@ if (distinctFieldNames!(Specs))
Returns:
A `size_t` representing the hash of this `Tuple`.
*/
size_t toHash() const nothrow @safe
size_t toHash() const nothrow @trusted
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can't be legitimately marked @trusted because hashOf(x) can call x.toHash() which may do any number of unsafe things. It also can't be @trusted because of the "Object.toHash() is not const" fiasco.

@n8sh
Copy link
Member

n8sh commented Aug 19, 2018

@ZombineDev I don't think it can be used there: you can't treat function arguments as compile-time constants even in an if (__ctfe) block. Or did you mean something else?

wilzbach added a commit to wilzbach/phobos that referenced this pull request Dec 31, 2018
TypeInfo is part of DRuntime.
See: dlang#5952

Replaced `toHash` with a parameter-less template for codegen on demand.
@wilzbach
Copy link
Member Author

Rebased and removed the @trusted. Looks like it's no longer required (:

CC @thewilsonator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants