Runtime: [System.Memory] Embedded Reference Types compiler bug

Created on 4 Dec 2017  路  34Comments  路  Source: dotnet/runtime

Code that was previously working (on 4.5.0-preview2-25707-02 , which seems to have disappeared!?) breaks on the latest preview: 4.5.0-preview1-26002-01, this is breaking deployment of new CI infrastructure as the working package is not obtainable. I have tried to hunt down the the issue, but it is beyond my understanding.

Repro steps

  1. dotnet new console

  2. dotnet add package System.Memory -v 4.5.0-preview1-26002-01 -s https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json

  3. Edit Program.cs and insert ReadOnlySpan<char> x = "hello".AsReadOnlySpan(); before the print statement
  4. Run dotnet build

Project file (repo.csproj)

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="System.Memory" Version="4.5.0-preview1-26002-01" />
  </ItemGroup>
</Project>

Source file (Program.cs)

锘縰sing System;

namespace repo
{
    class Program
    {
        static void Main(string[] args)
        {
            ReadOnlySpan<char> x = "hello".AsReadOnlySpan();
            Console.WriteLine("Hello World!");
        }
    }
}

Expected behavior

Expected that the above code works, the usage was taken from the Span doco (https://github.com/dotnet/corefxlab/blob/master/docs/specs/span.md)

Actual behavior

Compiler error:
Program.cs(10,12): error CS0619: 'ReadOnlySpan' is obsolete: 'Types with embedded references are not supported in this version of your compiler.' [/tmp/repo/repo.csproj]

Known workarounds

If you have a cached version of 4.5.0-preview2-25707-02 , you can use this and there will be no errors

Related information

Output of dotnet --info

.NET Command Line Tools (2.0.3)

Product Information:
 Version:            2.0.3
 Commit SHA-1 hash:  eb1d5ee318

Runtime Environment:
 OS Name:     debian
 OS Version:  9
 OS Platform: Linux
 RID:         linux-x64
 Base Path:   /usr/share/dotnet/sdk/2.0.3/

Microsoft .NET Core Shared Framework Host

  Version  : 2.0.3
  Build    : a9190d4a75f4a982ae4b4fa8d1a24526566c69df

Edit: Tagging area owners @KrzysztofCwalina and @ahsonkhan

area-System.Memory

Most helpful comment

@ahsonkhan I've confirmed this is an issue with ReSharper, as suspending it removes the error message - I'll open a ticket with JetBrains instead!

All 34 comments

If you add to .csproj

<LangVersion>7.2</LangVersion>

e.g.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <LangVersion>7.2</LangVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="System.Memory" Version="4.5.0-preview1-26002-01" />
  </ItemGroup>
</Project>

Does it fix it?

hi @benaadams , it seems only 7.1 is available on my machine: CSC : error CS1617: Invalid option '7.2' for /langversion; must be ISO-1, ISO-2, Default, Latest or a valid version in range 1 to 7.1.

cc @VSadov

I went back to a version close to the preview2 version that I can no longer find, and I struck gold with dotnet add package System.Memory -v 4.5.0-preview1-25730-02 -s https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json, which seems to raise the obsolete message as a warning instead of an error (but now I am scared this will also get removed from the feed).

If someone confirmed fixed on C# 7.2, I will have my work cut out for me (as I am using F#, just made the C# repro to rule out a F# compiler bug)...

Update: I installed the latest Net Compilers using NuGet (or so I think, the versioning is jumbled)

$ Microsoft.Net.Compilers.2.4.0/tools/csc.exe /r:/home/x/.nuget/packages/system.memory/4.5.0-preview1-26002-01/lib/netstandard2.0/System.Memory.dll /r:/home/x/.nuget/packages/runtime.linux-x64.microsoft.netcore.app/2.0.0/runtimes/linux-x64/lib/netcoreapp2.0/netstandard.dll /r:/home/x/.nuget/packages/system.runtime/4.3.0/lib/net462/System.Runtime.dll Program.cs 
Microsoft (R) Visual C# Compiler version 2.4.0.62122 (ab56a4a6)
Copyright (C) Microsoft Corporation. All rights reserved.

Program.cs(9,6): error CS0619: 'ReadOnlySpan<char>' is obsolete: 'Types with embedded references are not supported in this version of your compiler.'

Install this compiler package (notice .NETCore, not .NET):
Microsoft.NETCore.Compilers - 2.6.0-beta3-62316-02
https://dotnet.myget.org/feed/roslyn/package/nuget/Microsoft.NETCore.Compilers/2.6.0-beta3-62316-02

With this compiler, you will have support for LangVersion 7.2, although that shouldn't be necessary if you are only using 7.0 language features.

Also, you should be using the latest System.Memory package since there has been quite a bit of churn for Span/etc in the last few months (which looks like you are already doing).

https://dotnet.myget.org/feed/dotnet-core/package/nuget/System.Memory/4.5.0-preview1-26002-01

Please let me know if you are still having issues after this and I can try to help resolve it.

cc @agocke

@ahsonkhan I can confirm when using that beta compiler (2.6.0-beta3-62316-02) that the code compiles as expected. This is a bit problematic given that System.Memory is now locked into a specific language and compiler version (which means ill have to remove it as a dependency).

Is there any option for having a System.Memory that works with netstandard? The latest version that is listed on nuget is 4.4 (https://www.nuget.org/packages/System.Memory/4.4.0-preview2-25405-01) which appears to have issues when running within aspnetcore (might be another bug, but I figured nuget package was just outdated)

ahsonkhan Does this prevent F# from using System.Memory now?

cc @KevinRansom as well

This is a bit problematic given that System.Memory is now locked into a specific language and compiler version (which means ill have to remove it as a dependency).

As long as your code isn't using any of the new language features (like ref readonly/etc) then you don't need to bump your language version to use System.Memory.

The compiler update is there to ensure correct usage of Span and catch programming errors at compile time instead of the program crashing at runtime.

~What version of the dotnet cli are you using to compile your project?~
Edit: Just noticed the version info in the initial repro. If you use the latest preview cli, your app should compile fine as well without having to explicitly install the compiler package.

You can see the version if you run the dotnet --info command

Essentially, with the latest cli, I cannot repro the issue using your initial steps. Let me know if that works for you.

Is there any option for having a System.Memory that works with netstandard?

System.Memory should already work with netstandard. We have netstandard libraries today in corefxlab that reference System.Memory and work. Example:
https://github.com/dotnet/corefxlab/blob/master/src/System.Buffers.Primitives/System.Buffers.Primitives.csproj#L12

Does this prevent F# from using System.Memory now?

I don't see any reason why it would. It should still work as expected. Please let me know if you are observing any issues.
```f#
open System

[]
open System

[]
let main argv =
let array1 = [| 1; 2; 3 |]
let span = new Span(array1)
printfn "I am using Span of length %i" span.Length // I am using Span of length 3
0
```

@ahsonkhan it is a hard to debug this one. I am using dotnet cli 2.0.3.

As a bit more info, I found that the following is broken:

锘縰sing System;
namespace repo2
{
    class Program
    {
        static void Main(string[] args)
        {
            ReadOnlySpan<char> x = "asdf".AsReadOnlySpan();
            Console.WriteLine("Hello World!");
        }
    }
}

However, the following works:

锘縰sing System;

namespace repo2
{
    class Program
    {
        static void Main(string[] args)
        {
            var x = "asdf".AsReadOnlySpan();
            Console.WriteLine("Hello World!");
        }
    }
}

Note, as above, the bug does not manifest on compiler version 2.6.0-beta3-62316-02 only 2.3.1.61919 (57c81319)

Any reason why you can't update to newer preview dotnet cli?
https://github.com/dotnet/cli#installers-and-binaries

Hi @ahsonkhan, I am doing so now (sorry slow internet!)

I have hit https://github.com/aspnet/MetaPackages/issues/231, so this might take longer than expected

Compiler should complain regrdless of explicit type or var. It seems like a bug, but also could be long-standing behavior that is maintained for compatibility reasons.

Most uses of obsolete type should result in errors/warnings.

@ahsonkhan I can confirm that with .NET Command Line Tools (2.2.0-preview1-007622) and "System.Memory" Version="4.5.0-preview1-26002-01" that the error no longer occurs. Happy to close this ticket as the original issue is solved.

@VSadov I agree, it is a bit confusing.

Can someone point me in the right direction to convert code that previously used constructs like Dictionary<int, ReadOnlySpan<char>> ? It appears this is no longer possible? The type 'ReadOnlySpan<char>' may not be used as a type argument, I realise it is a bit unfair to ask this as this library is still in preview.

Can someone point me in the right direction to convert code that previously used constructs like

Span is a stackonly (by-ref like) type and cannot be used as a generic as that would box it. If you need a type that needs to live on the heap, consider using Memory<T>

See this for more information on ref-like types.

Closing the issue.

Right, excellent @ahsonkhan thank you for solving this one, which was really a problem on my end. In summary, it previously worked (boxing a Span) due to the compiler being less stringent about the correctness of boxing a stack only type (in other words, my code was working but probably broken!)

dotnet build works correctly in my case, however, vscode shows the error as a tooltip and in the 'problems' pane. I presume its not using the correct roslyn version but i can't figure out how to change that.

Please let me know if you are observing any issues.

@ahsonkhan I'm seeing this error with F# when using System.Memory 4.5.0-preview2-26216-03:

error FS0101: This construct is deprecated.
Types with embedded references are not supported in this version of your compiler.

I'm running the nightly versions of "F# Visual Tools" in VS, so I don't think I can get a newer compiler.

See tracking language suggestion at https://github.com/fsharp/fslang-suggestions/issues/648

@Porges Don't use Span with F# yet, it's unsafe because no compiler checks are done. You would run into runtime errors easily if misused :(

dotnet build works correctly in my case, however, vscode shows the error as a tooltip and in the 'problems' pane. I presume its not using the correct roslyn version but i can't figure out how to change that.

I see the same in Visual Studio 15.6.4 with C# 7.2 and it's very distracting. Any updates or workarounds I can use?

@JimBobSquarePants, can you please file a new issue with your scenario (along with a csproj that repros and output from dotnet --info)?

I can take a look and provide an update or workaround. Thanks!

I'm experiencing the same issue in Visual Studio 15.6.7 with VB 15.5.
I have added <LangVersion>Latest</LangVersion> in <PropertyGroup> in my .vbproj file. But this error is still showing. I clearly know that System.Span(Of T) can't be stored on heap, so I don't want to see the BC30668 error preventing me from compiling my code.
I have to downgrade System.Memory to 4.4.0-preview1-25305-02 to suppress this error.

I'm on VS 2017 15.7.1 and having this same problem with the latest .NET Core 2.1 RC. Strange thing is, if I set LangVersion to 7.2, it goes away - if it's latest or 7.3, the error comes back.

I'm on VS 2017 15.7.1 and having this same problem with the latest .NET Core 2.1 RC. Strange thing is, if I set LangVersion to 7.2, it goes away - if it's latest or 7.3, the error comes back.

Can you please share the source project for the repro and I will take a look. Also, can you share the output of donet.exe --info please. Thanks. I am assuming you are seeing this issue with a C# project (or is it VB?).

I'm experiencing the same issue in Visual Studio 15.6.7 with VB 15.5.

This is a compiler related issue specific to VB and I see we have an issue there already: https://github.com/dotnet/roslyn/issues/26752

I'm on VS 2017 15.7.1 and having this same problem with the latest .NET Core 2.1 RC.

I cannot reproduce this issue (with LangVersion 7.2 or 7.3).

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <LangVersion>7.3</LangVersion>
  </PropertyGroup>

</Project>

```C#
using System;

namespace Try73
{
class Program
{
static void Main(string[] args)
{
Span span = new byte[10];
Console.WriteLine(span.Length);
}
}
}
```

@cocowalla, @Nukepayload2, @JimBobSquarePants - please feel free to open a new issue if you see any other, reproducible issues with the System.Memory package or use of Span.

@ahsonkhan I'm ok now, apologies for not getting back to you. Turned out it was a Resharper bug.

@ahsonkhan I'm using c#, not VB. I can reproduce by creating a new project from template in VS - code exactly as you specified reproduces it.

@JimBobSquarePants I'm also using R#, but I'm already on the latest version - we're you able to fix this issue?

@cocowalla I'm fine now with Resharper 2018.1, using the System.Memory 4.5.0 RC1 though if that makes a difference.

@ahsonkhan I've confirmed this is an issue with ReSharper, as suspending it removes the error message - I'll open a ticket with JetBrains instead!

@cocowalla Any updates from jetbrains on this?

@bryaan JetBrains confirmed it was a problem, and said they'd fix it in the new release. I think they actually ending up having to issue another fix - but 2 versions on, I'm on 2018.1.2 and it seems to be OK 馃憤

Was this page helpful?
0 / 5 - 0 ratings