Skip to content

Commit 9ed4b77

Browse files
author
msftbot[bot]
authored
Merge pull request #49784 from dotnet/merges/release/dev16.8-to-release/dev16.8-vs-deps
Merge release/dev16.8 to release/dev16.8-vs-deps
2 parents 6559f38 + dedcd58 commit 9ed4b77

File tree

13 files changed

+198
-35
lines changed

13 files changed

+198
-35
lines changed

docs/contributing/Building, Debugging, and Testing on Windows.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ The minimal required version of .NET Framework is 4.7.2.
1515

1616
## Developing with Visual Studio 2019
1717

18-
1. [Visual Studio 2019 16.8p2](https://visualstudio.microsoft.com/downloads/)
18+
1. [Visual Studio 2019 16.8](https://visualstudio.microsoft.com/downloads/)
1919
- Ensure C#, VB, MSBuild, .NET Core and Visual Studio Extensibility are included in the selected work loads
20-
- Ensure Visual Studio is on Version "16.8 Preview 3" or greater
20+
- Ensure Visual Studio is on Version "16.8" or greater
2121
- Ensure "Use previews of the .NET Core SDK" is checked in Tools -> Options -> Environment -> Preview Features
2222
- Restart Visual Studio
23-
1. [.NET Core SDK 5.0 Release Candidate 2](https://dotnet.microsoft.com/download/dotnet-core/5.0) [Windows x64 installer](https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.100-rc.2-windows-x64-installer)
23+
1. [.NET Core SDK 5.0](https://dotnet.microsoft.com/download/dotnet-core/5.0) [Windows x64 installer](https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.100-windows-x64-installer)
2424
1. [PowerShell 5.0 or newer](https://docs.microsoft.com/en-us/powershell/scripting/setup/installing-windows-powershell). If you are on Windows 10, you are fine; you'll only need to upgrade if you're on earlier versions of Windows. The download link is under the ["Upgrading existing Windows PowerShell"](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-6#upgrading-existing-windows-powershell) heading.
2525
1. Run Restore.cmd
2626
1. Open Roslyn.sln

eng/build.ps1

+1
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,7 @@ function Prepare-TempDir() {
605605
$env:TMP=$TempDir
606606

607607
Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\.editorconfig") $TempDir
608+
Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\global.json") $TempDir
608609
Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\Directory.Build.props") $TempDir
609610
Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\Directory.Build.targets") $TempDir
610611
Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\Directory.Build.rsp") $TempDir

eng/targets/Imports.targets

-24
Original file line numberDiff line numberDiff line change
@@ -175,30 +175,6 @@
175175
</ItemGroup>
176176
</Target>
177177

178-
<!--
179-
Work around missing code fix references causing VBCSCompiler.exe to reject compilations.
180-
https://github.com/dotnet/roslyn/issues/46684
181-
-->
182-
<Target Name="ExcludeCodeFixes"
183-
BeforeTargets="CoreCompile"
184-
Condition="'$(UseRoslynAnalyzers)' != 'false' AND '$(BuildingProject)' == 'true'">
185-
<!--
186-
Disable analyzers that only provide code fixes.
187-
-->
188-
<ItemGroup>
189-
<Analyzer Remove="@(Analyzer)"
190-
Condition="'%(Filename)' == 'Microsoft.CodeAnalysis.CSharp.CodeStyle.Fixes'
191-
OR '%(Filename)' == 'Microsoft.VisualStudio.Threading.Analyzers.CodeFixes'"/>
192-
</ItemGroup>
193-
194-
<!--
195-
Explicitly reference Humanizer prior to https://github.com/dotnet/roslyn/pull/47297
196-
-->
197-
<ItemGroup>
198-
<Analyzer Include="$(NuGetPackageRoot)\humanizer.core\$(HumanizerCoreVersion)\lib\netstandard1.0\Humanizer.dll" />
199-
</ItemGroup>
200-
</Target>
201-
202178
<ItemGroup>
203179
<PackageDownload Include="Humanizer.Core" Version="[$(HumanizerCoreVersion)]" />
204180
</ItemGroup>

global.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"sdk": {
3-
"version": "5.0.100-rc.2.20479.15",
3+
"version": "5.0.100",
44
"allowPrerelease": true,
55
"rollForward": "major"
66
},
77
"tools": {
8-
"dotnet": "5.0.100-rc.2.20479.15",
8+
"dotnet": "5.0.100",
99
"vs": {
1010
"version": "16.8"
1111
},

src/Compilers/CSharp/Portable/FlowAnalysis/LocalDataFlowPass.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ internal interface ILocalDataFlowState : ILocalState
3232
/// <summary>
3333
/// A mapping from local variables to the index of their slot in a flow analysis local state.
3434
/// </summary>
35-
protected readonly PooledDictionary<VariableIdentifier, int> _variableSlot = PooledDictionary<VariableIdentifier, int>.GetInstance();
35+
protected PooledDictionary<VariableIdentifier, int> _variableSlot = PooledDictionary<VariableIdentifier, int>.GetInstance();
3636

3737
/// <summary>
3838
/// A mapping from the local variable slot to the symbol for the local variable itself. This

src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs

+110-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public VisitArgumentResult(VisitResult visitResult, Optional<LocalState> stateFo
118118
/// <summary>
119119
/// The inferred type at the point of declaration of var locals and parameters.
120120
/// </summary>
121-
private readonly PooledDictionary<Symbol, TypeWithAnnotations> _variableTypes = SpecializedSymbolCollections.GetPooledSymbolDictionaryInstance<Symbol, TypeWithAnnotations>();
121+
private PooledDictionary<Symbol, TypeWithAnnotations> _variableTypes = SpecializedSymbolCollections.GetPooledSymbolDictionaryInstance<Symbol, TypeWithAnnotations>();
122122

123123
/// <summary>
124124
/// Binder for symbol being analyzed.
@@ -192,6 +192,11 @@ public VisitArgumentResult(VisitResult visitResult, Optional<LocalState> stateFo
192192
/// </summary>
193193
private readonly bool _isSpeculative;
194194

195+
/// <summary>
196+
/// Is a method that contains only blocks, expression statements, and lambdas.
197+
/// </summary>
198+
private readonly bool _isSimpleMethod;
199+
195200
/// <summary>
196201
/// True if this walker was created using an initial state.
197202
/// </summary>
@@ -394,6 +399,7 @@ private NullableWalker(
394399
_returnTypesOpt = returnTypesOpt;
395400
_snapshotBuilderOpt = snapshotBuilderOpt;
396401
_isSpeculative = isSpeculative;
402+
_isSimpleMethod = IsSimpleMethodVisitor.IsSimpleMethod(node);
397403

398404
if (initialState != null)
399405
{
@@ -418,6 +424,68 @@ private NullableWalker(
418424
}
419425
}
420426

427+
internal sealed class IsSimpleMethodVisitor : BoundTreeWalkerWithStackGuard
428+
{
429+
private bool _hasComplexity;
430+
431+
internal static bool IsSimpleMethod(BoundNode? node)
432+
{
433+
if (node is BoundConstructorMethodBody constructorBody && constructorBody.Initializer is { })
434+
{
435+
return false;
436+
}
437+
if (node is BoundMethodBodyBase methodBody)
438+
{
439+
var blockBody = methodBody.BlockBody;
440+
var expressionBody = methodBody.ExpressionBody;
441+
node = blockBody;
442+
if (node is { })
443+
{
444+
if (expressionBody is { }) return false;
445+
}
446+
else
447+
{
448+
node = expressionBody;
449+
}
450+
}
451+
var visitor = new IsSimpleMethodVisitor();
452+
try
453+
{
454+
visitor.Visit(node);
455+
return !visitor._hasComplexity;
456+
}
457+
catch (CancelledByStackGuardException)
458+
{
459+
return false;
460+
}
461+
}
462+
463+
public override BoundNode? Visit(BoundNode? node)
464+
{
465+
if (node is null)
466+
{
467+
return null;
468+
}
469+
if (_hasComplexity)
470+
{
471+
return node;
472+
}
473+
if (node is BoundExpression)
474+
{
475+
return base.Visit(node);
476+
}
477+
switch (node.Kind)
478+
{
479+
case BoundKind.Block:
480+
case BoundKind.ExpressionStatement:
481+
case BoundKind.ReturnStatement:
482+
return base.Visit(node);
483+
}
484+
_hasComplexity = true;
485+
return node;
486+
}
487+
}
488+
421489
public string GetDebuggerDisplay()
422490
{
423491
if (this.IsConditionalState)
@@ -2535,6 +2603,37 @@ private void AnalyzeLocalFunctionOrLambda(
25352603
var oldState = this.State;
25362604
this.State = state;
25372605

2606+
var oldVariableSlot = _variableSlot;
2607+
var oldVariableTypes = _variableTypes;
2608+
var oldVariableBySlot = variableBySlot;
2609+
var oldNextVariableSlot = nextVariableSlot;
2610+
2611+
// As an optimization, if the entire method is simple enough,
2612+
// we'll reset the set of variable slots and types after analyzing the nested function,
2613+
// to avoid accumulating entries in the outer function for variables that are
2614+
// local to the nested function. (Of course, this will drop slots associated
2615+
// with variables in the outer function that were first used in the nested function,
2616+
// such as a field access on a captured local, but the state associated with
2617+
// any such entries are dropped, so the slots can be dropped as well.)
2618+
// We don't optimize more complicated methods (methods that contain labels,
2619+
// branches, try blocks, local functions) because we track additional state for
2620+
// those nodes that might be invalidated if we drop the associated slots or types.
2621+
if (_isSimpleMethod)
2622+
{
2623+
_variableSlot = PooledDictionary<VariableIdentifier, int>.GetInstance();
2624+
foreach (var pair in oldVariableSlot)
2625+
{
2626+
_variableSlot.Add(pair.Key, pair.Value);
2627+
}
2628+
_variableTypes = SpecializedSymbolCollections.GetPooledSymbolDictionaryInstance<Symbol, TypeWithAnnotations>();
2629+
foreach (var pair in oldVariableTypes)
2630+
{
2631+
_variableTypes.Add(pair.Key, pair.Value);
2632+
}
2633+
variableBySlot = new VariableIdentifier[oldVariableBySlot.Length];
2634+
Array.Copy(oldVariableBySlot, variableBySlot, oldVariableBySlot.Length);
2635+
}
2636+
25382637
var previousSlot = _snapshotBuilderOpt?.EnterNewWalker(lambdaOrFunctionSymbol) ?? -1;
25392638

25402639
var oldPending = SavePending();
@@ -2576,6 +2675,16 @@ private void AnalyzeLocalFunctionOrLambda(
25762675

25772676
_snapshotBuilderOpt?.ExitWalker(this.SaveSharedState(), previousSlot);
25782677

2678+
if (_isSimpleMethod)
2679+
{
2680+
nextVariableSlot = oldNextVariableSlot;
2681+
variableBySlot = oldVariableBySlot;
2682+
_variableTypes.Free();
2683+
_variableTypes = oldVariableTypes;
2684+
_variableSlot.Free();
2685+
_variableSlot = oldVariableSlot;
2686+
}
2687+
25792688
this.State = oldState;
25802689
_returnTypesOpt = oldReturnTypes;
25812690
_useDelegateInvokeParameterTypes = oldUseDelegateInvokeParameterTypes;

src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionPerfTests.cs

+71
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using Microsoft.CodeAnalysis.CSharp.Syntax;
56
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
67
using Roslyn.Test.Utilities;
78
using System.Linq;
@@ -373,5 +374,75 @@ public void ArrayInitializationAnonymousTypes()
373374
var comp = CreateCompilation(source);
374375
comp.VerifyEmitDiagnostics();
375376
}
377+
378+
[Fact]
379+
[WorkItem(49745, "https://github.com/dotnet/roslyn/issues/49745")]
380+
public void NullableStateLambdas()
381+
{
382+
const int nFunctions = 10000;
383+
384+
var builder = new StringBuilder();
385+
builder.AppendLine("#nullable enable");
386+
builder.AppendLine("class Program");
387+
builder.AppendLine("{");
388+
builder.AppendLine(" static void F1(System.Func<object, object> f) { }");
389+
builder.AppendLine(" static void F2(object arg)");
390+
builder.AppendLine(" {");
391+
for (int i = 0; i < nFunctions; i++)
392+
{
393+
builder.AppendLine($" F1(arg{i} => arg{i});");
394+
}
395+
builder.AppendLine(" }");
396+
builder.AppendLine("}");
397+
398+
var source = builder.ToString();
399+
var comp = CreateCompilation(source);
400+
comp.VerifyDiagnostics();
401+
402+
CheckIsSimpleMethod(comp, "F2", true);
403+
}
404+
405+
[Theory]
406+
[InlineData("class Program { static object F() => null; }", "F", true)]
407+
[InlineData("class Program { static void F() { } }", "F", true)]
408+
[InlineData("class Program { static void F() { { } { } { } } }", "F", true)]
409+
[InlineData("class Program { static void F() { ;;; } }", "F", false)]
410+
[InlineData("class Program { static void F2(System.Action a) { } static void F() { F2(() => { }); } }", "F", true)]
411+
[InlineData("class Program { static void F() { void Local() { } } }", "F", false)]
412+
[InlineData("class Program { static void F() { System.Action a = () => { }; } }", "F", false)]
413+
[InlineData("class Program { static void F() { if (true) { } } }", "F", false)]
414+
[InlineData("class Program { static void F() { while (true) { } } }", "F", false)]
415+
[InlineData("class Program { static void F() { try { } finally { } } }", "F", false)]
416+
[InlineData("class Program { static void F() { label: F(); } }", "F", false)]
417+
[WorkItem(49745, "https://github.com/dotnet/roslyn/issues/49745")]
418+
public void NullableState_IsSimpleMethod(string source, string methodName, bool expectedResult)
419+
{
420+
var comp = CreateCompilation(source);
421+
var diagnostics = comp.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error);
422+
diagnostics.Verify();
423+
CheckIsSimpleMethod(comp, methodName, expectedResult);
424+
}
425+
426+
private static void CheckIsSimpleMethod(CSharpCompilation comp, string methodName, bool expectedResult)
427+
{
428+
var tree = comp.SyntaxTrees[0];
429+
var model = (CSharpSemanticModel)comp.GetSemanticModel(tree);
430+
var methodDeclaration = tree.GetCompilationUnitRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Single(m => m.Identifier.ToString() == methodName);
431+
var methodBody = methodDeclaration.Body;
432+
BoundBlock block;
433+
if (methodBody is { })
434+
{
435+
var binder = model.GetEnclosingBinder(methodBody.SpanStart);
436+
block = binder.BindEmbeddedBlock(methodBody, new DiagnosticBag());
437+
}
438+
else
439+
{
440+
var expressionBody = methodDeclaration.ExpressionBody;
441+
var binder = model.GetEnclosingBinder(expressionBody.SpanStart);
442+
block = binder.BindExpressionBodyAsBlock(expressionBody, new DiagnosticBag());
443+
}
444+
var actualResult = NullableWalker.IsSimpleMethodVisitor.IsSimpleMethod(block);
445+
Assert.Equal(expectedResult, actualResult);
446+
}
376447
}
377448
}

src/Interactive/HostProcess/InteractiveHost64.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<PropertyGroup>
66
<Prefer32Bit>false</Prefer32Bit>
77
<OutputType>Exe</OutputType>
8-
<TargetFrameworks>net472;net5.0-windows</TargetFrameworks>
8+
<TargetFrameworks>net472;net5.0-windows7.0</TargetFrameworks>
99
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
1010
<UseWindowsForms>true</UseWindowsForms>
1111

src/Interactive/HostTest/InteractiveHost.UnitTests.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
</CopyPublishedOutputProjectReference>
4141

4242
<CopyPublishedOutputProjectReference Include="..\HostProcess\InteractiveHost64.csproj">
43-
<SetTargetFramework>TargetFramework=net5.0-windows</SetTargetFramework>
43+
<SetTargetFramework>TargetFramework=net5.0-windows7.0</SetTargetFramework>
4444
<OutputItemType>InteractiveHostFiles_Core</OutputItemType>
4545
</CopyPublishedOutputProjectReference>
4646
</ItemGroup>

src/VisualStudio/IntegrationTest/TestUtilities/VisualStudioInstanceFactory.cs

+2
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ private static Process StartNewVisualStudioProcess(string installationPath, int
364364
// influences.
365365
processStartInfo.Environment.Remove("DOTNET_MULTILEVEL_LOOKUP");
366366
processStartInfo.Environment.Remove("DOTNET_INSTALL_DIR");
367+
processStartInfo.Environment.Remove("DotNetRoot");
368+
processStartInfo.Environment.Remove("DotNetTool");
367369

368370
// The first element of the path in CI is a .dotnet used for the Roslyn build. Make sure to remove that.
369371
if (processStartInfo.Environment.TryGetValue("BUILD_SOURCESDIRECTORY", out var sourcesDirectory))

src/VisualStudio/Setup/Roslyn.VisualStudio.Setup.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@
269269
<ProjectReference Include="..\..\Interactive\HostProcess\InteractiveHost64.csproj">
270270
<Name>InteractiveHost.Core64</Name>
271271

272-
<SetTargetFramework>TargetFramework=net5.0-windows</SetTargetFramework>
272+
<SetTargetFramework>TargetFramework=net5.0-windows7.0</SetTargetFramework>
273273
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
274274
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
275275

src/Workspaces/CoreTestUtilities/Roslyn.Services.UnitTests.Utilities.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<PropertyGroup>
55
<OutputType>Library</OutputType>
66
<RootNamespace>Microsoft.CodeAnalysis.UnitTests</RootNamespace>
7-
<TargetFrameworks>net5.0-windows;netcoreapp3.1;net472</TargetFrameworks>
7+
<TargetFrameworks>net5.0-windows7.0;netcoreapp3.1;net472</TargetFrameworks>
88
<UseWpf>true</UseWpf>
99
<IsShipping>false</IsShipping>
1010
<ExcludeFromSourceBuild>true</ExcludeFromSourceBuild>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
// this file is empty to ensure we get the "standard" behavior as if
3+
// no global.json was specified in the first place
4+
}

0 commit comments

Comments
 (0)