lunditoph-siago / Sia.NET

Modern ECS framework for .NET
BSD 3-Clause "New" or "Revised" License
8 stars 1 forks source link

Compiler Error CS8157 #21

Closed Sieluna closed 5 months ago

Sieluna commented 5 months ago

Describe the bug

In Entity.cs, compiler will confuse at Get and GetOrNull function

image

Steps to reproduce

using System.Runtime.CompilerServices;

public class Program
{
    public static void Main()
    {
        var s = new S();
        ref var b = ref s.G<bool>();
        Console.WriteLine($"{b}");
    }
}

struct S
{
    byte i;

    public ref TComponent G<TComponent>()
    {
        ref byte byteRef = ref i;
        nint offset = 1;
        return ref Unsafe.As<byte, TComponent>(ref Unsafe.AddByteOffset(ref byteRef, offset));
    }
}

Will throw compile error, which can be fixed by

-        return ref Unsafe.As<byte, TComponent>(ref Unsafe.AddByteOffset(ref byteRef, offset));
+        return ref Unsafe.AsRef(ref Unsafe.As<byte, TComponent>(ref Unsafe.AddByteOffset(ref byteRef, offset)));

Logs

No response

Sieluna commented 5 months ago

Host.UnsafeGetByteRef will return a managed type reference, it should be safe.

using System.Runtime.CompilerServices;

var s = new E(new H<char>(new B<char>(['B', 'e', 's', 't', ',', 'S', 'i', 'a'])));
ref var b = ref s.G<char>();
Console.WriteLine($"{b}");

struct B<T>(T[] b)
{
    public readonly ref T GetRef(int i)
        => ref b[i];
}

struct H<TEntity>(B<TEntity> b)
{
    public ref byte UnsafeGetByteRef()
        => ref Unsafe.As<TEntity, byte>(ref b.GetRef(0));
}

struct E(H<char> h)
{
    public ref TComponent G<TComponent>()
    {
        ref var byteRef = ref h.UnsafeGetByteRef();
        nint offset = 2;
        return ref Unsafe.As<byte, TComponent>(ref Unsafe.AddByteOffset(ref byteRef, offset));
    }
}

Expect e, result e