d使引用计数析构器为@safe打破了DIP1000

原文
如果设置std.conv.RefCounted的析构器为@safe,则下面的代码用-preview=dip1000成功编译,但不应如此.如果使用中域而不是域容器局部,它编译正确的,但用户不应手动.编译器不应编译逃避局部引用的易错代码.参考

import std.stdio;
import std.typecons;

struct Container
{
    int[] data;
}

void main ()
{
    auto ptr = getPtr();
    writeln(ptr);
    const save = ptr.dup;
    auto other = getPtr();
    assert(save == ptr);
}

int[] getPtr ()
{
    int[42] local;
    return getPtr2(Container(local));
}

int[] getPtr2 (scope Container local)
{
    RefCounted!Container rc = local;
    return rc.refCountedPayload().data;
}

能简化为不导入Phobos的独立测试用例吗?
因为按@system推导引用计数析构造器,顶部添加@safe:会停止编译.
2.098-dip1000,也检测到逃逸引用计数构造器的局部变量.
@safe似乎不可能逃逸本地静态数组,所以该问题似乎不再有效?
但是,对上面拉请目标,即使解决引用计数实现中的问题,引用计数切片(即使是变相)也不能使析构器@safe,因为:

void test() @safe {
    auto slice = makeSomeKindOfRefCountedSlice!int(10);
    int[] local = slice.payload.data;

    static assert(!__traits(compiles, &slice)); // 域
    static assert(!__traits(compiles, &local)); // 域

    slice = slice.init; // 0并释放
    local[1] = 32; // 在@safe函数中用后释放
}

需要定义仅返回临时变量函数的方法(这样不会编译上面的int[]local=slice.payload.data行).在可以之前,该类引用计数切片的@safe析构器仅按惯例是安全的(即,要点?)

posted @ 2022-08-31 21:16  zjh6  阅读(14)  评论(0)    收藏  举报  来源