std.typecons: Make RefCounted pure nothrow @nogc when possible#4832
std.typecons: Make RefCounted pure nothrow @nogc when possible#4832andralex merged 1 commit intodlang:masterfrom
Conversation
895012c to
642710c
Compare
std/typecons.d
Outdated
| // qualified C memory allocations | ||
| private @safe pure nothrow @nogc: | ||
| void* malloc(size_t size); | ||
| void free(void* ptr); |
There was a problem hiding this comment.
Ok. But its usage here can be @trusted.
There was a problem hiding this comment.
I see, you made it private too. Hmmm...
|
OK how about you keep the safe but for now drop the pure. The notion of marking |
I would point out that we're in the same boat with the GC and So, I don't know what the right answer is, but there's definitely an argument that |
|
@jmdavis new is special so we can special case it |
|
AFAICT, C-style memory allocations cannot be qualified correctly in D using Instead we have to qualify the code that it's using C-style allocation logic and privately import |
That's not a requirement of D's
GC.malloc and GC.free aren't really special, though. They can be used just like C's malloc and free. Yet GC.malloc and GC.free are GC.malloc being (weakly) See also http://forum.dlang.org/post/hrwnhprgcjlbypaecpzg@forum.dlang.org.
Actually, the compiler must not do that. It does right now, but that's issue 15862. |
|
@aG0aep6G I think it's a slippery slope that GC.malloc and free are marked as pure. I don't like that, and I don't like that used as a precedent. There must be some acknowledgment at a point that our type system has limitations that doesn't allow it to express certain valid programs. |
This needs to be sorted out. Either it's wrong that GC.malloc and GC.free are marked
Ok, but I don't think it's a good idea to draw that line between GC.malloc and C's malloc. |
642710c to
9894282
Compare
|
Hmmm, this notion of a function that returns data with mutable indirection is very interesting. In particular, if the data returned has mutable indirections leading to values that cannot be present in the parameters, that means that's "fresh" data, i.e. newly allocated. Consider: pure int[] fun(float[]);Without even looking at the definition, the compiler can infer that the array of integers is freshly-allocated for the simple reason there's no other place it could come from :o). Being able to characterize "fresh" without making language addition can be a big win. For now, I agree that fixing https://issues.dlang.org/show_bug.cgi?id=15862 would allow us to make malloc pure. |
9894282 to
1055e95
Compare
Yeah, dmd uses this to allow implicit conversion to immutable when the value comes from a pure function (and other requirements are met). This example compiles with int* f() pure { return new int; }
void main() { immutable p = f(); }
I'm not so sure about that example. fun is allowed to cast the argument to int[], isn't it? Then again, dmd seems to disregard that possibility, too. This is currently accepted: pure int[] fun(float[] arg) { return cast(int[]) arg; }
void main() { float[] a = [1, 2, 3]; immutable i = fun(a); }If dmd is correct here, that would mean casting from one array type to another is invalid (aka has undefined behavior), wouldn't it? That doesn't seem right. I'd say this is another bug in dmd, and it cannot be assumed that fun returns a unique result. Filed as issue 16585. |
1055e95 to
b3ef825
Compare
Current coverage is 89.27% (diff: 75.00%)@@ master #4832 diff @@
==========================================
Files 121 121
Lines 76114 76116 +2
Methods 0 0
Messages 0 0
Branches 0 0
==========================================
+ Hits 67950 67956 +6
+ Misses 8164 8160 -4
Partials 0 0
|
The bug has been fixed ;-) So what's still blocking this? |
|
The |
|
I think instead of marking Make a private binding to pragma(mangle, "free") extern(C) private purefree(void *mem) pure;Then you can call it in one place where we can control the context, and not expose the whole world. EDIT: Well, now that I look at your PR, that's pretty much exactly what you are doing! Why would this require making the actual binding in core.stdc pure? |
|
@schveiguy, It doesn't. I just thought making Further, we need to do the same for |
|
Let's go with the private declaration for now. Yes, in the future we do want to make functions like |
or my existing? |
|
b3ef825 to
d2802dc
Compare
|
Made it so, @andralex |
d2802dc to
a9e7c9b
Compare
andralex
left a comment
There was a problem hiding this comment.
All good, please fix coverage.
std/typecons.d
Outdated
| onOutOfMemoryError(); | ||
| static if (hasIndirections!T) | ||
| GC.addRange(&_store._payload, T.sizeof); | ||
| pure_gc_addRange(&_store._payload, T.sizeof); |
std/typecons.d
Outdated
| { | ||
| extern(C) private pure nothrow @nogc static // TODO remove pure when https://issues.dlang.org/show_bug.cgi?id=15862 has been fixed | ||
| { | ||
| pragma(mangle, "free") void pure_free( void *ptr ); |
There was a problem hiding this comment.
unusual naming convention (pureFree would be preferred)
There was a problem hiding this comment.
Ok to leave it as this?
std/typecons.d
Outdated
| extern(C) private pure nothrow @nogc static // TODO remove pure when https://issues.dlang.org/show_bug.cgi?id=15862 has been fixed | ||
| { | ||
| pragma(mangle, "free") void pure_free( void *ptr ); | ||
| pragma(mangle, "gc_addRange") void pure_gc_addRange( in void* p, size_t sz, const TypeInfo ti = null ); |
There was a problem hiding this comment.
Eh, apparently not that unusual :)
There was a problem hiding this comment.
That's why I used underscore instead. Ok to leave it as this? Or should I use pureGCAddRange?
There was a problem hiding this comment.
Kill the TODO, that bug has been fixed, and you still need pure anyway.
nordlow
left a comment
There was a problem hiding this comment.
Feedback on local namings.
std/typecons.d
Outdated
| { | ||
| extern(C) private pure nothrow @nogc static // TODO remove pure when https://issues.dlang.org/show_bug.cgi?id=15862 has been fixed | ||
| { | ||
| pragma(mangle, "free") void pure_free( void *ptr ); |
There was a problem hiding this comment.
Ok to leave it as this?
std/typecons.d
Outdated
| extern(C) private pure nothrow @nogc static // TODO remove pure when https://issues.dlang.org/show_bug.cgi?id=15862 has been fixed | ||
| { | ||
| pragma(mangle, "free") void pure_free( void *ptr ); | ||
| pragma(mangle, "gc_addRange") void pure_gc_addRange( in void* p, size_t sz, const TypeInfo ti = null ); |
There was a problem hiding this comment.
That's why I used underscore instead. Ok to leave it as this? Or should I use pureGCAddRange?
|
Don't worry about the name, let's get the coverage. Thx! |
a9e7c9b to
f036125
Compare
| { | ||
| struct S { int* p; } | ||
|
|
||
| auto s = RefCounted!S(null); |
There was a problem hiding this comment.
This makes line 5003 covered.
|
Next up is |
|
I think this looks good. Let's wait and see whether dlang/druntime#1735 is merged or not. If so, then you need to have a |
|
If dlang/druntime#1735 gets merged we can use Update: purity was reverted in dlang/druntime#1735 Should we merge this or use |
|
@nordlow I guess this is next! |
|
Made it use What about local purity of |
f036125 to
4a9da6e
Compare
|
local is fine for now |
|
Changed naming of local wrappers to D-style casing. This is ready, @andralex ! |
Acked-by: Per Nordlöw <per.nordlow@gmail.com>
4a9da6e to
ddebfaf
Compare
|
@nordlow you have style failures, see ci/circleci |
|
@andralex That's actually a dscanner error. It isn't working correctly with the new DIP1000 syntax. |
|
So what to do until DIP-1000 works, @andralex ? |
|
Auto-merge toggled on |
|
Great! |
This makes
RefCounted!Tpure/nothrow/@nogcwhen possible.