Sdk: Result of chr() cannot be used as initial value of a Const in .Net Core 3 Preview 1

Created on 4 Jan 2019  路  16Comments  路  Source: dotnet/sdk

Version: 3.0.100-preview-009812
Commit: e3abf6e935

Runtime Environment:
OS Name: Windows
OS Version: 10.0.17763
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.0.100-preview-009812\

Host (useful for support):
Version: 3.0.0-preview-27122-01
Commit: 00c5c8bc40

Have you experienced this same bug with .NET Framework?: No

In the .Net Framework using VB.Net you can compile this Line:

Private Const TabChar As Char = Chr(9)

In .Net Core 3 Preview 1 it failes with:
error BC30059: Constant expression is required.

Most helpful comment

This works

  <Target Name="SetVBRuntimePath" AfterTargets="ResolveAssemblyReferences">
    <PropertyGroup>
      <VBRuntime Condition="'%(ReferencePath.FileName)' == 'Microsoft.VisualBasic'">%(ReferencePath.Identity)</VBRuntime>
    </PropertyGroup>
  </Target>

It is basically doing what @AlekseyTs said: if there's an microsoft.visualbasic.dll in the references, use that. I will base the real fix around this.

All 16 comments

@jaredpar I think this belongs in Roslyn. Can you move?

@vcsjones i think it actually belongs here. This is a VB runtime issue and the VB runtime code lives here.

CC @333fred, @cston

Thanks to some help from @AlekseyTs, I've identified the initial problem here. The issue that, by default, the dotnet sdk passes /vbruntime* to the compiler, which causes Roslyn to embed vbcore into the resulting binary. Vbcore already has a Microsoft.VisualBasic.Strings which does not have a definition for Chr, so the check to replace Chr(9) at compile time fails, causing the BC30059 error.

@nguerrera, the fix that needs to happen here is that, for .NET Core 3 projects, the SDK should not be telling roslyn to embed vbcore by default, or these types of errors will crop up.

And magically this has transferred to SDK

I'm not sure about the exact fix needed here.

First, I don't know the history of the defaulting VBRuntime=Embed in the SDK. If you follow renames it goes all the way back to the very first PR that supported VB at all:

Using VBCore (VBRuntime=Embed) to not introduce new dependencies.

@srivatsn @davkean Do you remember more details on this?

@jaredpar @AlekseyTs @333fred What is the precise condition where VBRuntime should not be Embed? Is it really TargetFrameworkIdentifier == .NETCoreApp and TargetFrameworkVersion >= 3.0? What about .NETStandard or even .NETFramework?

Also, when not setting it to Embed, should we leave it empty, set VBRuntime=Default, or something else?

See https://github.com/dotnet/roslyn/blob/9e012fe3596974e5e208b556f87891c5b0d0e331/src/Compilers/Core/MSBuildTask/Vbc.cs#L443-L466

A little bit aside, but another annoyance is that this is set in .props before we can check things like the TFM today. To base it on TFM or any other property, the defaulting has to move to targets, but that's technically a a breaking change as the default value of the property would no longer be observable in the body of the .vbproj.

Final question: is there any VS UI that corresponds to the VBRuntime setting. I didn't find any, but moving defaults around can break that.

cc @KathleenDollard

What is the precise condition where VBRuntime should not be Embed?

I think this condition should be - if a Microsoft.VisualBasic.Dll is going to be passed as a reference, VB runtime should not be embedded. Otherwise, we end up with two different implementations of VB runtime at the same time.

Hi,
Any Update on this?
I just tried to convert a VB.Net Project from the Old Project Format into the SDK Project Format and noticed that I ran into the Very same problem.

Still in Preview 5

@nguerrera did we make changes to the targets to support this scenario?

No. The bug is still open.

@nguerrera So what does the outlook for finding a solution to this appear to be? As you notice, it's not just isolated to CHR and Strings in general... it extends to a lot of other VB specific functionality as identified in #3387 and #3379.

@DualBrain as a workaround, you can set the VBRuntime property to default in your vbproj file and the embedded VB runtime will not be used, allowing the referenced MS.VB.dll to be used instead.

When I set VBRuntime to default, I get

vbc : error BC2017: could not find library 'Microsoft.VisualBasic.dll' [D:\Temp\vb\vb.vbproj]

However, there is a Microsoft.VisualBasic.dll passed via /r.

Seems we have to set VBRuntime to a path: https://github.com/dotnet/sdk/issues/3387#issuecomment-506560645

This works

  <Target Name="SetVBRuntimePath" AfterTargets="ResolveAssemblyReferences">
    <PropertyGroup>
      <VBRuntime Condition="'%(ReferencePath.FileName)' == 'Microsoft.VisualBasic'">%(ReferencePath.Identity)</VBRuntime>
    </PropertyGroup>
  </Target>

It is basically doing what @AlekseyTs said: if there's an microsoft.visualbasic.dll in the references, use that. I will base the real fix around this.

Was this page helpful?
0 / 5 - 0 ratings