How to cast `shared` away reliably
Arafel
er.krali at gmail.com
Tue Feb 10 21:14:36 UTC 2026
So, first of all, a bit of background - I just hit this regression:
https://github.com/dlang/dmd/issues/22556
TLDR: I just want / need a reliable way to get exactly `T` from `shared
(T)`.
The core question is that there is no reliable way to "peel" away
`shared`, at leas from slices or AAs. You can do it if you cast to the
exact (unshared) type by hand, but this isn't always feasible,
especially in generic / templated code.
IOW, one would reasonably expect that for any type `T`, and `S` being
`shared (T)`, if you use `cast ()` on a variable of type `S`, you'd get
back `T`, right?
```d
alias Unshared(T) = typeof(cast() T.init);
template sanity(T) {
alias S = shared(T);
static if(is(T==Unshared!S)) {
enum sanity = true;
} else {
enum sanity = false;
}
}
static assert(sanity!int); // PASSES
static assert(sanity!(int[])); // FAILS
static assert(sanity!(int[int])); // FAILS
```
OK, let's try a more powerful `is` expression then:
```d
template BetterUnshared(S) {
static if (is(S == shared(T), T)) {
alias BetterUnshared = T;
}
}
template sanity(T) {
alias S = shared(T);
static if(is(T == BetterUnshared!S)) {
enum sanity = true;
} else {
enum sanity = false;
}
}
static assert(sanity!int); // still PASSES
static assert(sanity!(int[])); // still FAILS
static assert(sanity!(int[int])); // still FAILS
```
And we still get an extra `shared` popping out of nowhere:
```d
alias SII = shared(int[int]);
template BetterUnshared(S) {
static if (is(S == shared(T), T)) {
alias BetterUnshared = T;
}
}
pragma(msg, BetterUnshared!SII); // shared(int)[int]
```
I assume the root cause is this:
```d
static assert(is(shared(int[]) == shared(shared(int)[])));
static assert(is(shared(int[int]) == shared(shared(int)[int])));
```
Is this desirable / documented anywhere?
Again, I just want / need a reliable way to get exactly `T` from `shared
(T)`.
More information about the Digitalmars-d
mailing list