Allow index initialisers to be used in fixed size buffers.#39805
Allow index initialisers to be used in fixed size buffers.#39805YairHalberstadt wants to merge 2 commits intodotnet:mainfrom
Conversation
| typeArgumentsWithAnnotations: default(ImmutableArray<TypeWithAnnotations>), | ||
| invoked: false, | ||
| indexed: false, | ||
| indexed: allInitialiserExpressionsAreIndexExpression(), |
There was a problem hiding this comment.
It feels like it would be better to just make this a local above this statement.
| static void Main() | ||
| { | ||
| var b = new S(); | ||
| b.V[0] = 0; |
There was a problem hiding this comment.
I'm confused, wasn't this meant to test an object initializer?
| } | ||
| }"; | ||
| CreateCompilation(source, options: TestOptions.UnsafeDebugDll) | ||
| .VerifyDiagnostics(); |
There was a problem hiding this comment.
.VerifyDiagnostics(); [](start = 16, length = 21)
For success cases we prefer executing the code and observing that it behaves as expected.
|
This should be dependent on language version 7.3 (or probably class C
{
unsafe void M()
{
C1 c = new C1()
{
S = { X = { [0] = 1, [2] = 2 } }
};
}
}
unsafe struct S1
{
public fixed int X[10];
}
class C1
{
public S1 S;
} |
| static void M() | ||
| { | ||
| var b = new S { V = { 1 } }; | ||
| b = new S { V = { Prop = 1 } }; |
There was a problem hiding this comment.
{ Prop = 1 } [](start = 24, length = 12)
Consider also testing with an empty initializer and with an initializer that mixes assignments (indexed followed by non-indexed and in reversed order).
|
Done with review pass (iteration 1) |
changes based on review. add more tests.
|
|
||
| static void Main() | ||
| { | ||
| var c = new C { S = new S { V = |
There was a problem hiding this comment.
Do we have a test that shows that the following fails: new S { V = { 0, 1, 2 } }
There was a problem hiding this comment.
Yes in Unsafe tests (Semantic instead of CodeGen tests)
|
Would you be able to assign someone to this please? Thanks |
|
I actually don't buy @gafter's reasoning here. The spec has this to say about fixed and moveable variables:
My read of this is that In this case, the bug here has nothing to do with fixed-size buffer indexing, which was added in C# 7.3, but the simple fact that the unnamed temporary here is being incorrectly referred to as moveable, when it is actually supposed to be fixed. |
|
@agocke |
|
We should definitely take this. Only question is what language version to require. I haven't looked at the implementation yet, I'll try to get to that today. |
agocke
left a comment
There was a problem hiding this comment.
Sorry for the delay, really messed up my local Git clone on Friday and had to fix it before I could review this
| { | ||
| var memberName = (IdentifierNameSyntax)namedAssignment.Left; | ||
|
|
||
| var allInitializerExpressionsAreIndexExpressions = |
There was a problem hiding this comment.
Yeah, this looks wrong. If my read of the spec is correct, the categorization of the receiver is non-moveable. So we shouldn't need to know if these are index expressions in the example
using System;
unsafe struct S
{
public fixed double V[3];
static void Main()
{
var s = new S { V =
{
[0] = 0,
[1] = 1,
[2] = 2,
} };
Console.Write(s.V[0]);
Console.Write(s.V[1]);
Console.Write(s.V[2]);
}
}I think the problem may be in Binder.IsMoveableVariable. Initializers should create a BoundObjectOrCollectionValuePlaceholder and, by my read, that placeholder is always a local temporary and thus immoveable.
Fixes #39632
Code Gen requires no changes. We just remove an incorrect error.