Vivek MVK
Vivek MVK

Reputation: 1179

CS8347/CS8352 with "ref struct" and "in" / "ref" parameter

I have a function with following signature

State MoveForward(in Path path);

Path is a ref struct
State is also a ref struct with just integer.

Now I have another helper function

bool TryMoveForward(in Path path, ref State state)
{
    // which does something like:
    state = MoveForward(path); // "line A"
    return !state.IsEnd(); // IsEnd determined by integer != -1
}

At the "line A" I am getting the error CS8347: Cannot use a result of 'MoveForward' in this context because it may expose variables referenced by parameter 'path' outside of their declaration scope.

But I think this shouldn't be the case or atleast compiler can be smart enough to avoid throwing this error for few reasons:

  1. State is created just with integers (Compiler can look into the usage of path). There is no reference exposed from "path"
  2. "State" is a ref struct which doesn't carry any "ref" to escape with.

How can I make compiler not complain about this?

I don't understand whether it is a problem of assigning something to ref State state or passing the path to in parameter.

If I remove in in MoveForward the error goes away. I want to keep the "in"

If I split the line, I don't have any way to avoid the error. eg:

    var result = MoveForward(path); // "line A"
    state = result;
    return !state.IsEnd(); // IsEnd determined by integer != -1

Getting CS8352: Cannot use variable 'result' in this context because it may expose referenced variables outside of their declaration scope.

state has its own memory in stack and result should be able to be copied to state similar to single line statement.

Upvotes: 2

Views: 130

Answers (1)

D A
D A

Reputation: 2072

Based on this explanations https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/low-level-struct-improvements.md#keywords-vs-attributes

Opt out is a keyword (scoped) but the opt in is an attribute ([UnscopedRef]). So in your case you must defined it as scoped:

State MoveForward(scoped in Path path)

Upvotes: 2

Related Questions