roslyn: Type `T[]*` reports parser error
Version Used:
VS 17.5p1
Steps to Reproduce:
Type a code snippet that uses int[]*
:
#pragma warning disable CS8500
static unsafe long IterateBits(long* array, int length, int* @out)
{
var baseVec = Vector256.Create(-1);
var incVec = Vector256.Create(64);
var add8 = Vector256.Create(8);
var initOut = @out;
for (var i = 0; i < length; i++)
{
var w = array[i];
if (w == 0)
{
baseVec += incVec;
}
else
{
for (var k = 0; k < 4; k++)
{
var byteA = (byte)w;
var byteB = (byte)(w >> 8);
w >>= 16;
// ↓ here
fixed (int[]* pVt = BitPosTable)
// ~~~~~~
fixed (int* pByteA = pVt[byteA], pByteB = pVt[byteB])
{
var vecA = Vector256.Load(pByteA);
var vecB = Vector256.Load(pByteB);
var advanceA = LengthTable[byteA];
var advanceB = LengthTable[byteB];
vecA = baseVec + vecA;
baseVec += add8;
vecB = baseVec + vecB;
baseVec += add8;
Vector256.Store(vecA, @out);
@out += advanceA;
Vector256.Store(vecB, @out);
@out += advanceB;
}
}
}
}
return @out - initOut;
}
Expected Behavior:
No parser error on int[]*
: C# 11 allows managed-typed pointers.
Actual Behavior:
It seems that C# syntax parser cannot correctly handle the expression int[]*
; we should add an extra but unnecessary token ?
to make parser behave well: int[]?*
.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 1
- Comments: 15 (14 by maintainers)
This strikes me as a case of using grammars to enforce semantic rules, which we don’t really do in the implementation. The “grammar” effectively in use in the implementation permits parsing many invalid programs simply so we can have a better guess at what the user meant to do. The corresponding spot in the grammar generated by the implementation is:
https://github.com/dotnet/roslyn/blob/1c349c7032ec178955a8fcccc62015ee39b00031/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4#L400-L402
Since we are downgrading the pointer to managed type from error to warning in unsafe context, we might want to adjust the standard for C# 11 to indicate that pointers can also refer to managed types.
When parsing a type, the parser says: if we got
*
and previous token was]
, don’t parse. So adding the?
in between makes the parser happy.Gotcha. Then making this change def makes sense to me.