Bug 23140 – Array!T where T is a shared class no longer works
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2022-05-25T14:16:36Z
Last change time
2022-08-30T09:25:05Z
Keywords
pull
Assigned to
No Owner
Creator
Steven Schveighoffer
Comments
Comment #0 by schveiguy — 2022-05-25T14:16:36Z
I'm not sure it should have ever worked, but I'm also wondering why this cannot be made to work.
Prior to 2.099.0, the following code compiled:
```d
import std.container : Array;
shared class C {}
Array!C arr;
```
But it no longer does. The reason is because of the fix for https://issues.dlang.org/show_bug.cgi?id=22515. Now, a C is actually typed as `shared(C)`, and it does not implicitly cast to `const void *` (used by GC functions and pureFree, etc.).
Three options here:
1. Fix Array to cast away the shared when using these functions (a reasonable assumption)
2. Fix the druntime functions so they also accept `shared` pointers
3. close this bug as wontfix, and I'll have to work around it in the project I'm trying to compile (libasync)
Comment #1 by rubytheroobster — 2022-08-03T14:01:34Z
(In reply to Steven Schveighoffer from comment #0)
> I'm not sure it should have ever worked, but I'm also wondering why this
> cannot be made to work.
>
> Prior to 2.099.0, the following code compiled:
>
> ```d
> import std.container : Array;
> shared class C {}
>
> Array!C arr;
> ```
>
> But it no longer does. The reason is because of the fix for
> https://issues.dlang.org/show_bug.cgi?id=22515. Now, a C is actually typed
> as `shared(C)`, and it does not implicitly cast to `const void *` (used by
> GC functions and pureFree, etc.).
>
I'm currently working on a fix, and I've noticed the following:
While creating an Unshared template (https://forum.dlang.org/post/[email protected]),
and doing the following solved most of the problems:
```d
//...
struct Array(W) //Changed from struct Array(T)
if (!is(immutable W == immutable bool)) //Change 'T' to 'W'
{
alias T = Unshared!W; //Fix https://issues.dlang.org/show_bug.cgi?id=23140
//...
```
This doesn't fix the constructor for Array.
I still get the following error message:
```
E:\Programs\D\dmd2\windows\bin\..\..\src\phobos\std\container\array.d(650): Error: none of the overloads of template `std.container.array.Array!(shared(C)).Array.__ctor` are callable using argument types `!()(C[])`
E:\Programs\D\dmd2\windows\bin\..\..\src\phobos\std\container\array.d(575): Candidates are: `__ctor(U)(U[] values...)`
E:\Programs\D\dmd2\windows\bin\..\..\src\phobos\std\container\array.d(605): `__ctor(Range)(Range r)`
with `Range = C[]`
must satisfy the following constraint:
` !is(Range == T[])`
```
> Three options here:
>
> 1. Fix Array to cast away the shared when using these functions (a
> reasonable assumption)
> 2. Fix the druntime functions so they also accept `shared` pointers
> 3. close this bug as wontfix, and I'll have to work around it in the project
> I'm trying to compile (libasync)
Comment #2 by dlang-bot — 2022-08-03T14:34:50Z
@RubyTheRoobster created dlang/phobos pull request #8525 "fix issue 23140" fixing this issue:
- Fix issue 23140 - Array!T where T is a shared class no longer works
https://github.com/dlang/phobos/pull/8525
Comment #3 by dlang-bot — 2022-08-03T15:43:09Z
@RubyTheRoobster created dlang/phobos pull request #8526 "fix issue 23140" fixing this issue:
- Fix issue 23140 - Array!T where T is a shared class no longer works
https://github.com/dlang/phobos/pull/8526
Comment #4 by razvan.nitu1305 — 2022-08-08T11:26:02Z
(In reply to Steven Schveighoffer from comment #0)
> I'm not sure it should have ever worked, but I'm also wondering why this
> cannot be made to work.
>
> Prior to 2.099.0, the following code compiled:
>
> ```d
> import std.container : Array;
> shared class C {}
>
> Array!C arr;
> ```
>
> But it no longer does. The reason is because of the fix for
> https://issues.dlang.org/show_bug.cgi?id=22515. Now, a C is actually typed
> as `shared(C)`, and it does not implicitly cast to `const void *` (used by
> GC functions and pureFree, etc.).
>
> Three options here:
>
> 1. Fix Array to cast away the shared when using these functions (a
> reasonable assumption)
From my perspective, it should be illegal to cast away the sharedness if an aggregate was defined `shared struct/class T` (this could be extended to any type qualifier, but let's just stick to shared). If the user opted to define the aggregate as such, I think it is reasonable to assume that any use of such an object is going to violate the definition of the object.
> 2. Fix the druntime functions so they also accept `shared` pointers
In my opinion, this is the most sensible approach.
> 3. close this bug as wontfix, and I'll have to work around it in the project
> I'm trying to compile (libasync)
Comment #5 by rubytheroobster — 2022-08-10T14:52:55Z
(In reply to RazvanN from comment #4)
> (In reply to Steven Schveighoffer from comment #0)
> > I'm not sure it should have ever worked, but I'm also wondering why this
> > cannot be made to work.
> >
> > Prior to 2.099.0, the following code compiled:
> >
> > ```d
> > import std.container : Array;
> > shared class C {}
> >
> > Array!C arr;
> > ```
> >
> > But it no longer does. The reason is because of the fix for
> > https://issues.dlang.org/show_bug.cgi?id=22515. Now, a C is actually typed
> > as `shared(C)`, and it does not implicitly cast to `const void *` (used by
> > GC functions and pureFree, etc.).
> >
> > Three options here:
> >
> > 1. Fix Array to cast away the shared when using these functions (a
> > reasonable assumption)
>
> From my perspective, it should be illegal to cast away the sharedness if an
> aggregate was defined `shared struct/class T` (this could be extended to any
> type qualifier, but let's just stick to shared). If the user opted to define
> the aggregate as such, I think it is reasonable to assume that any use of
> such an object is going to violate the definition of the object.
>
> > 2. Fix the druntime functions so they also accept `shared` pointers
>
> In my opinion, this is the most sensible approach.
Or you could just cast to void* in the function call (which doesn't break free/pureFree)
>
> > 3. close this bug as wontfix, and I'll have to work around it in the project
> > I'm trying to compile (libasync)
Comment #6 by rubytheroobster — 2022-08-15T19:52:12Z
The pull request has been merged.
Comment #7 by dlang-bot — 2022-08-30T09:25:05Z
dlang/phobos pull request #8548 "merge stable" was merged into master:
- f293250cd8475d72acf583d3156382b73cf78339 by RubyTheRoobster:
Fix issue 23140 - Array!T where T is a shared class no longer works
- 2023b271e560ab59cd6e5a9453331f5adf96f44b by RubyTheRoobster:
Fix issue 23140 - Array!T where T is a shared class no longer works
- 36efa13efbd8a2882f6f999d900400b5515e39b4 by The Dlang Bot:
Merge pull request #8526 from RubyTheRoobster/fix-23140
fix issue 23140
Signed-off-by: Dennis <[email protected]>
Merged-on-behalf-of: Dennis <[email protected]>
https://github.com/dlang/phobos/pull/8548