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.

Reply via email to