-
-
Notifications
You must be signed in to change notification settings - Fork 707
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
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.
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.
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.
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.
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:
injectNamedFields
gets 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 */ }();
toHash
usestypeid(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.
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!
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
@@ -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 |
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.
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.
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;
}
}
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 fail at runtime which is strictly worse then compile-time failure.
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.
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 |
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'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]); |
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.
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.
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
.
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.
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
?
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 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
@@ -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 |
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 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
-betterC
compatibility 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
.