The compiler turns the SetI local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign to readonly fields from it.
So the compiler takes this:
public class A
{
    private readonly int i;
    public A()
    {
        void SetI()
        {
            i = 10; 
        }
        SetI();
    }
}
and turns it into this:
public class A
{
    private readonly int i;
    public A()
    {
        <.ctor>g__SetI|1_0();
    }
    [CompilerGenerated]
    private void <.ctor>g__SetI|1_0()
    {
        i = 10;
    }
}
(SharpLab. I left off the readonly so it would compile.)
As you can see, it's trying to assign i from the method <.ctor>g__SetI|1_0(), which isn't a constructor.
Unfortunately the C# 7.0 language specification hasn't yet been published, so I can't quote it.
Exactly the same happens if you try and use a delegate:
public class A
{
    private readonly int i;
    public A()
    {
        Action setI = () => i = 10;
        setI();
    }
}
Gets compiled to:
public class A
{
    private readonly int i;
    public A()
    {
        Action action = <.ctor>b__1_0;
        action();
    }
    [CompilerGenerated]
    private void <.ctor>b__1_0()
    {
        i = 10;
    }
}
(SharpLab, again without the readonly.)
... which likewise fails to compile.