Seems calling dispose on an interface does not work. The following will cause free to fail: // someOutputRange is a ubyte[] output range of type O auto malloc = Mallocator.instance; OutputRange!(ubyte[]) range; range = malloc.make!(OutputRangeObject!(O, ubyte[]))(someOutputRange); // do some stuff... malloc.dispose(range); It fails because typeid on interfaces is wonky, who thought that was a good idea... It can be fixed by changing to: malloc.dispose(cast(Object)range); But honestly it should not be necessary and will 100% trip people up.
GCAllocator is supported but Mallocator produces a free error: import std.experimental.allocator.mallocator; import std.experimental.allocator.gc_allocator; import std.experimental.allocator; interface Foo {} class Bar: Foo {} void main() { GCAllocator.instance.dispose(cast(Foo) GCAllocator.instance.make!Bar); // comment the following line: OK Mallocator.instance.dispose(cast(Foo) Mallocator.instance.make!Bar); }
I think this is safe to change dispose to: void dispose(A, T)(auto ref A alloc, T p) if (is(T == class) || is(T == interface)) { if (!p) return; auto support = (cast(void*) cast(Object) p)[0 .. typeid(p).init.length]; destroy(p); alloc.deallocate(support); } deallocate doesn't care about the the length of initial static layout of a class.
Commits pushed to master at https://github.com/D-Programming-Language/phobos https://github.com/D-Programming-Language/phobos/commit/211c10aff2b2cdfd9280f159cab7825b8a323c80 fixed issue 15721 https://github.com/D-Programming-Language/phobos/commit/e55e196127c75899a36016cba12b8cbd5c1548d9 Merge pull request #4022 from BBasile/issue-15721 fixed issue 15721 - std.experimental.allocator dispose on interface