Further changes to std.typecons.Unique#3225
Conversation
|
I am very opposed to leaving |
|
Unique!Object u;
assert(!u);
u = unique!Object();
assert(u);
if(u) {
// Valid
} else {
// Invalid
}And so forth. If you want to avoid leaving the cast token in your source code, you can use |
|
|
|
In practice I assume most uses of the |
Should I really explain why this statement is wrong? :) |
|
@JakobOvrum can you provide free function that check if its argument Unique is initialized? AFAIR D name resolution rules, it shouldn't take priority over member function : http://dpaste.dzfl.pl/5977af784165 |
|
(it can have longish name like |
|
It is true in practice for Phobos. Even the statically allocated exception thrown from |
|
All issues I know are about mutable pre-allocated exceptions. What is the issue with |
|
The exception system in D is fundamentally broken in terms of non-mutable exceptions: void main()
{
static immutable ex = new Exception("");
bool caught = false;
try throw ex;
catch(Exception e)
{
caught = true;
e.next = null;
}
assert(caught);
}Not only is the immutable exception caught as a mutable reference, but the exception infrastructure doesn't care about immutability either, it will happily mutate It has been discussed here and elsewhere in the past. |
a5c53f6 to
408af38
Compare
|
Added |
Fix destruction Deprecate `empty` in favour of `cast(bool)` and a free function`isValidUnique` Make initialization a precondition of `get` for non-class types
408af38 to
ca12d3e
Compare
|
Does anyone know what the failures are about? They don't manifest on Windows... Does it mean there's a memory leak somewhere? |
If you comment out line 257 it doesn't error. I'm too busy atm to look into this any further, I hope that helps. |
There was a problem hiding this comment.
No need to deprecate the function, we just added it.
You could add a deprecated alias for the previously existing isEmpty though, just in case someone used it.
In practice all uses will be in if statements, there is no use for a named function b/c Unique is a truth value itself. if (uniq) {}
immutable val = uniq ? true : false;
immutable val2 = !!uniq; |
See this comment. Ping @Dicebot |
|
Yeah I don't think I have anything to add there. |
|
Sorry I'm late to the party. Ideally, I wanted to allow I'm certainly with @Dicebot - there should be some function to indicate if the
Now that I think about it, none of this would be an issue if D didn't use |
Yes, which is enabled because of
Your code is wrong. The correct code illustrates the issue: auto ppi = refCounted!(int*);
ppi = null; // same as ppi.get = null;
ppi.nullify;
|
You really think that's a blocker, given that |
|
Note that our design space is restricted to remain somewhat compatible with the existing RefCounted. |
|
Maybe we should simply go with isEmpty. Resetting can be done using object.destroy. |
|
Regardless of the rest of our discussion, I agree with @JakobOvrum's initial assessment that Would it be a decent compromise to disable |
Doable, but it would require forwarding of opEquals and opAssign, not the most elegant solution b/c it's not possible to forward rvalues as rvalues. |
|
That seems like a bit of a misnomer too, and something I was hoping we could move away from when we work I would wager that we're all tired of splitting hairs on this naming and convention issue, but
Because of these points I don't think we should introduce breaking changes to any of these types ( |
|
@JakobOvrum - I just did some experimenting which may put your concerns to rest - see the commit above I just made to my branch. Unlike Even for non-class reference types (e.g. // Unlike the current Nullable, assigning to null doesn't work,
// making confusion between the effects of "= null" and "nullify" moot.
auto uo = unique!Object();
// uo = null; // Error: forwards to get(), which returns an rvalue for classes
assert(uo);
uo.nullify();
assert(!uo);
auto up = unique!(int*);
assert(up);
int actual = 42;
up.get() = &actual;
// up = null; // Also donesn't work (no opAssign for typeof null)
assert(up);
up.nullify();
assert(!up);With this brought to light, can we please
|
|
Ah, b/c we already have an opAssign, that's also true for RefCounted. Sounds like a plan. |
|
To be completely transparent, there still might be some confusion with |
|
We can't deprecate the existing behavior of RefCounted without a very good reason, so maybe we should leave opEquals alone. |
|
Sounds fine to me - we can talk more about what to do with RefCounted in PRs related to it. |
|
Can we move on with this @JakobOvrum? |
|
I'll open a separate pull request. |
|
@MartinNowak Did you end up cutting another PR for this? |
|
And what's the plan for this with 2.068? I haven't been following the release schedule carefully, but if a new version is around the corner, perhaps we should defer this (and back out #3139) until we can get details hashed out and a plan for related changes to |
|
@mrkline I believe there's not going to be last minute PRs accepted anymore to streamline the release process/reduce regressions. So, that would mean this isn't going to be part of 2.068. |
|
@rsw0x: Right - my main point was that we should back out #3139 if we're not going to push this through for 2.068. Let's not change |
Andrei thinks, it's important enough to push the whole Unique/RefCounted stuff into the next release. |
|
Sorry for my general inactivity. My day job and life have been rather busy, but I should be back in the action to help with whatever you need. So,
|
It's fine, I'm working on all of the remaining issues. Currently trying to get the attributes for class destructors right, which is tricky b/c of polymorphism.
He meant 2.068, so the immediately next release.
Yes, I've based my work on your changes. |
|
Yikes, another attribute nightmare. Here is my branch btw, https://github.com/MartinNowak/phobos/tree/smartRefs. |
Sweet! I misread you originally as "we're putting it off for the release after 2.068 so we can take the time to finalize stuff".
Great. Let me know when you open a PR on your branch. There's a few things to discuss besides the WIP destructor magic, such as:
These are just things I noticed by trying to compile |
this is true, but some(?) unit-tests should be |
|
Well, yes, but I don't know how unit tests would test |
See the discussion in dlang#3225
Yes you can, you need to use attribute inference in such a way that
Yes they are, and I already did that on my branch. Same as #3259 (comment), closed in favor of a complete solution to smart refs. |
Follow-up to #3139.
emptyin favour ofcast(bool)geting non-class values, to supportnothrowgetis still a template with two overloads because it's the only way to make the documentation show them both, as far as I can tell.Deprecation of
emptyCurrently there are two ways to check the validity of a
Uniquereference,emptyandcast(bool). I think we should only have one, and that iscast(bool):emptyis not only a bad name as it implies a range or container, but is highly likely to hijackT.emptyin user code, which could conceivably cause hard to catch bugs ("why does it claim my unique container/range is never empty??").Initialization now a precondition for
geting non-class valuesThis is required to support
nothrow. I plan on working on other attributes, particularly@safe, once #3031 is ready and merged.What do you guys think?
edit:
BTW, what's up with deprecations not showing up in documentation?