On 6/9/23 06:05, An Pham wrote:
Getting with below error for following codes. Look like bug?
onlineapp.d(61): Error: scope variable `a` assigned to non-scope
parameter `a` calling `foo`
@safe:
struct A(S = string)
{
@safe:
S s;
void delegate() c;
}
struct B(S = string)
{
@safe:
@disable this();
this(C!S c, A!S a)
{
this.c = c;
this.a = a;
}
C!S foo()
{
return c;
}
A!S a;
C!S c;
}
class C(S = string)
{
@safe:
C!S foo(A!S a)
{
auto o = new Object();
return foo2(o, a);
}
C!S foo2(Object n, A!S a)
{
auto b = B!S(this, a);
return b.foo();
}
}
unittest
{
static struct X
{
@safe:
void foo3()
{
}
}
X x;
A!string a;
a.s = "foo";
a.c = &x.foo3;
auto c = new C!string();
c.foo(a);
}
void main()
{
}
I think the behavior you are seeing here is by design. There are two
things happening:
- There is no `scope` inference for virtual methods, as it is impossible
to get the inference right without knowing all overriding methods in
advance.
- You cannot mark the parameter `a` `scope`, because the lifetimes of
`this` and `a` become conflated within `b` in the body of `foo2` when
calling the constructor of `B!S`, and `this` is subsequently escaped.
As Dennis points out, a workaround is to mark the parameter `a` `return
scope`. However, this may lead to other problems down the line, as `a`
is never actually escaped.