Make std.typecons.Tuple betterC compatible#5952
Conversation
|
Thanks for your pull request, @wilzbach! Bugzilla referencesYour 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 locallyIf 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) $< |
There was a problem hiding this comment.
-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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
There are two culprits here:
injectNamedFieldsgets codegened -> we need to make sure that it exist only in CTFE context. One way to do this is to implement it asenum injectNamedFields = { /* code */ }();
toHashusestypeid(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 usingcore.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.
There was a problem hiding this comment.
Worked like a charm. Thanks!
TypeInfo is part of DRuntime. See: dlang#5952
TypeInfo is part of DRuntime. See: dlang#5952 Replaced `toHash` with a parameter-less template for codegen on demand.
TypeInfo is part of DRuntime. See: dlang#5952 Replaced `toHash` with a parameter-less template for codegen on demand.
std/typecons.d
Outdated
| A `size_t` representing the hash of this `Tuple`. | ||
| */ | ||
| size_t toHash() const nothrow @trusted | ||
| size_t toHash()() const nothrow @trusted |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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;
}
}There was a problem hiding this comment.
That would fail at runtime which is strictly worse then compile-time failure.
There was a problem hiding this comment.
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.
TypeInfo is part of DRuntime. See: dlang#5952 Replaced `toHash` with a parameter-less template for codegen on demand.
TypeInfo is part of DRuntime. See: dlang#5952 Replaced `toHash` with a parameter-less template for codegen on demand.
TypeInfo is part of DRuntime. See: dlang#5952 Replaced `toHash` with a parameter-less template for codegen on demand.
TypeInfo is part of DRuntime. See: dlang#5952 Replaced `toHash` with a parameter-less template for codegen on demand.
|
Finally got around rebasing this. It looks like we can get around the problems of the |
PetarKirov
left a comment
There was a problem hiding this comment.
I'm glad to see that this finally working!
std/typecons.d
Outdated
| static foreach (i, T; Types) | ||
| {{ | ||
| const k = typeid(T).getHash((() @trusted => cast(const void*) &field[i])()); | ||
| const k = hashOf(field[i]); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
@wilzbach hashOf void arrays is currently working in druntime master.
|
Opened a separate PR that just adds the testsuite (#6640), s.t. we can already add the betterC testsuite. |
TypeInfo is part of DRuntime. See: dlang#5952 Replaced `toHash` with a parameter-less template for codegen on demand.
|
Well, we can't use |
test/betterC/typecons.d
Outdated
| @@ -0,0 +1,7 @@ | |||
| extern(C) void main() | |||
There was a problem hiding this comment.
Can you now move it inside std.typecons as a @BetterC unittest?
There was a problem hiding this comment.
I can/will do this once #6645 has been merged.
|
Unfortunately, |
|
@n8sh the enum function trick used in this PR may help for |
std/typecons.d
Outdated
| A `size_t` representing the hash of this `Tuple`. | ||
| */ | ||
| size_t toHash() const nothrow @safe | ||
| size_t toHash() const nothrow @trusted |
There was a problem hiding this comment.
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.
|
@ZombineDev I don't think it can be used there: you can't treat function arguments as compile-time constants even in an |
TypeInfo is part of DRuntime. See: dlang#5952 Replaced `toHash` with a parameter-less template for codegen on demand.
|
Rebased and removed the |
I'm not sure how people want to start testing
-betterCcompatibility with Phobos. I assume the best way would be to do extract all unittests marked with@betterC?For now I went with a more simple and straight-forward way of simply executing all files in
test/betterC.