How to cast `shared` away reliably

Arafel er.krali at gmail.com
Wed Feb 11 02:02:20 UTC 2026


On 2/10/26 23:56, H. S. Teoh wrote:
> On Tue, Feb 10, 2026 at 10:14:36PM +0100, Arafel via Digitalmars-d wrote:
>> 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)`.
> [...]
> 
> I thought Phobos has an Unqual!T template that does exactly that.
> 
> Well OK, it strips away more than just shared, but you should be able to
> achieve what you want by looking at how Unqual is implemented.
> 
> 
> T
> 

Nope, exact same issue:

```d
import std;

alias SII = shared(int[int]);

pragma(msg, Unqual!SII); // still "shared(int)[int]"
```

And, for the record, I _can_ create a workaround that passes all the 
tests that I could come up with:

```d
template ReallyUnshared(S) {
     static if (is(S == shared(K[V]), K,V)) {
         alias ReallyUnshared = K[V]; // Why is `K` not shared here? Who 
knows...
     } else static if (is(S == shared(T[]), T)) { // Same here
         alias ReallyUnshared = T[];
     // } else static if (is(S == shared(T[n]), T,n)) { // You'd expect 
this to work, but it doesn't
     //     alias ReallyUnshared = T[n]; // Don't ask me why
     } else static if (__traits(isStaticArray, S)) {
         alias ReallyUnshared = typeof(cast () S.init[0])[S.length];
     } else static if (is(S == shared(T), T)) {
         alias ReallyUnshared = T;
     } else {
         alias ReallyUnshared = S;
     }
}

template sanity(T) {
     alias S = shared(T);
     static if(is(T == ReallyUnshared!S)) {
         enum sanity = true;
     } else {
         enum sanity = false;
     }
}

static assert(sanity!int);
static assert(sanity!(int[]));
static assert(sanity!(int[5]));
static assert(sanity!(int[int]));
```

The problem is:

a) It's a kludge, ugly as hell.
b) I have no way of knowing what other corner cases I might be missing.
c) There *MUST* be a clean way to do it.
d) It's terribly inconsistent behaviour and, I suspect, unintended: I 
would be relying on something that could change with some random 
refactoring or whatever.


More information about the Digitalmars-d mailing list