title: Passing both stackalloc'ed Span<T> and by-ref struct as arguments
body: <p>I am using a <code>SequenceReader&lt;T&gt;</code> to copy contents from a <code>ReadOnlySequence&lt;T&gt;</code> into different <code>Span&lt;T&gt;</code>. However, I get a compiler error when I try to encapsulate the copy logic into a separate function and want to call it with a <code>Span&lt;T&gt;</code> allocated on the stack.</p>
  
  <pre class="lang-cs prettyprint-override"><code>var sequence = new ReadOnlySequence&lt;byte&gt;(new byte[20]); // Source data to copy
  
  Span&lt;byte&gt; heap = new byte[10]; // Target location 1
  Span&lt;byte&gt; stack = stackalloc byte[10]; // Target location 2
  
  var reader = new SequenceReader&lt;byte&gt;(sequence);
  
  TryReadInto(ref reader, heap); // This is fine
  TryReadInto(ref reader, stack); // Gives compile time error CS8350
  </code></pre>
  
  <p>Since the instance method <a href="https://docs.microsoft.com/en-us/dotnet/api/system.buffers.sequencereader-1.trycopyto?view=netcore-3.1" rel="nofollow noreferrer"><code>TryCopyTo</code></a> on <code>SequenceReader&lt;T&gt;</code> does not advance the reader, I have created a higher level function that takes care of that:</p>
  
  <pre><code>[MethodImpl(MethodImplOptions.AggressiveInlining)]
  static bool TryReadInto(ref SequenceReader&lt;byte&gt; reader, Span&lt;byte&gt; destination)
  {
      if (reader.TryCopyTo(destination)) {
          reader.Advance(destination.Length);
          return true;
      }
  
      return false;
  }
  </code></pre>
  
  <p>As long as the destination is heap allocated everything works fine. But when the destination is allocated using <code>stackalloc</code> the compiler complains with a <em>CS8350: This combination of arguments to is disallowed because it may expose variables referenced by parameter outside of their declaration scope</em>.</p>
  
  <p>When I do not pass the reader as reference that compiler error goes away, but it is required for the reader to be passed as reference since <code>SequenceReader&lt;T&gt;</code> <a href="https://docs.microsoft.com/en-us/dotnet/standard/io/buffers#sequencereadert-common-problems" rel="nofollow noreferrer">is a mutable struct</a> and the position is advanced within the function.</p>
  
  <p>I get the compiler error. Parameter <code>reader</code> could be allocated in an earlier stack frame and as a ref-like struct would be able to have a <code>Span&lt;T&gt;</code> as a field. The method body could make the second (stack-allocated) parameter <code>destination</code> escape it's own stack frame, thus a function call with both a <code>ref</code>-parameter and a stack-allocated <code>Span&lt;T&gt;</code> is illegal in C#.</p>
  
  <p><strong>However, how am I able to encapsulate my logic then?</strong> <code>SequenceReader&lt;T&gt;</code> is a closed type so I can't just add an instance method. When I just inline the function call manually I do not get compiler errors. I guess the compiler sees that the reader is allocated in the same stack frame as the stack-allocated <code>Span&lt;byte&gt;</code>. Passing the reader by value is not an options since <code>SequenceReader&lt;T&gt;</code> <a href="https://docs.microsoft.com/en-us/dotnet/standard/io/buffers#sequencereadert-common-problems" rel="nofollow noreferrer">is a mutable struct</a>.</p>