diff --git a/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs b/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs
index 6c06f87c84b628b7114a82be82bc13e018722e15..137c953f8076ed1b4c15c8c3a7c7ee282f980909 100644
--- a/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs
+++ b/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs
@@ -112,7 +112,7 @@ public TypeWithAnnotations GetInferredReturnType(ConversionsBase conversions, Nu
// will be called again from NullableWalker.ApplyConversion when the
// BoundLambda is converted to an anonymous function.
// https://github.com/dotnet/roslyn/issues/31752: Can we avoid generating extra
- // diagnostics? And is this exponential when there are nested lambdas
+ // diagnostics? And is this exponential when there are nested lambdas?
var returnTypes = ArrayBuilder<(BoundReturnStatement, TypeWithAnnotations)>.GetInstance();
var diagnostics = DiagnosticBag.GetInstance();
var delegateType = Type.GetDelegateType();
diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.DebugVerifier.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.DebugVerifier.cs
index 2a5314b5d7a7a2b2b92b1d2f44b23e8c06b7db0a..0a8026ed7c1caac4fdeaa3bd97e437c8b7995d54 100644
--- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.DebugVerifier.cs
+++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.DebugVerifier.cs
@@ -56,7 +56,7 @@ protected override BoundExpression VisitExpressionWithoutStackGuard(BoundExpress
public override BoundNode Visit(BoundNode node)
{
- // Ensure that we always have a checkpoint for every BoundExpression in the map
+ // Ensure that we always have a snapshot for every BoundExpression in the map
if (_snapshotManager != null && node != null)
{
_snapshotManager.VerifyNode(node);
diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.SnapshotManager.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.SnapshotManager.cs
index 6a042a818aecb28a584f04fac7d67c19ff782f33..1cb6ccc2e309f6b7e38394816e01c4d48cecd86b 100644
--- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.SnapshotManager.cs
+++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.SnapshotManager.cs
@@ -14,7 +14,7 @@ internal sealed partial class NullableWalker
internal sealed class SnapshotManager
{
///
- /// The int key corresponds to .
+ /// The int key corresponds to .
///
private readonly ImmutableArray _walkerGlobalStates;
///
@@ -53,7 +53,7 @@ private SnapshotManager(ImmutableArray walkerGlobalStates, Im
return null;
}
- var globalState = _walkerGlobalStates[incrementalSnapshot.GlobalStateIndex];
+ var globalState = _walkerGlobalStates[incrementalSnapshot.SharedStateIndex];
var variableState = new VariableState(globalState.VariableSlot, globalState.VariableBySlot, globalState.VariableTypes, incrementalSnapshot.VariableState.Clone());
var method = globalState.Symbol as MethodSymbol;
return new NullableWalker(
@@ -79,7 +79,7 @@ internal void VerifyNode(BoundNode node)
}
Debug.Assert(_incrementalSnapshots.ContainsKey(node.Syntax.SpanStart), $"Did not find a snapshot for {node} `{node.Syntax}.`");
- Debug.Assert(_walkerGlobalStates.Length > _incrementalSnapshots[node.Syntax.SpanStart].GlobalStateIndex, $"Did not find global state for {node} `{node.Syntax}`.");
+ Debug.Assert(_walkerGlobalStates.Length > _incrementalSnapshots[node.Syntax.SpanStart].SharedStateIndex, $"Did not find global state for {node} `{node.Syntax}`.");
}
#endif
@@ -89,6 +89,7 @@ internal void VerifyNode(BoundNode node)
///
private sealed class DescendingIntComparer : IComparer
{
+ internal static readonly DescendingIntComparer Singleton = new DescendingIntComparer();
public int Compare(int x, int y) => y.CompareTo(x);
}
@@ -99,7 +100,7 @@ internal sealed class Builder
///
/// Snapshots are kept in a dictionary of position -> snapshot at that position. These are stored in descending order.
///
- private readonly ImmutableSortedDictionary.Builder _incrementalSnapshots = ImmutableSortedDictionary.CreateBuilder(new DescendingIntComparer());
+ private readonly ImmutableSortedDictionary.Builder _incrementalSnapshots = ImmutableSortedDictionary.CreateBuilder(DescendingIntComparer.Singleton);
///
/// Every walker is walking a specific symbol, and can potentially walk each symbol multiple times
/// to get to a stable state. Each of these symbols gets a single global state slot, which this
@@ -161,7 +162,7 @@ internal void TakeIncrementalSnapshot(BoundNode node, LocalState currentState)
}
///
- /// Contains the shared state state used to restore the walker at a specific point
+ /// Contains the shared state used to restore the walker at a specific point
///
internal struct SharedWalkerState
{
@@ -190,12 +191,12 @@ internal struct SharedWalkerState
private readonly struct Snapshot
{
internal readonly LocalState VariableState;
- internal readonly int GlobalStateIndex;
+ internal readonly int SharedStateIndex;
internal Snapshot(LocalState variableState, int globalStateIndex)
{
VariableState = variableState;
- GlobalStateIndex = globalStateIndex;
+ SharedStateIndex = globalStateIndex;
}
}
}
diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
index cd15c97d3c8f395915c277c16b2bd52ea0fbcd1b..f073b679c64ca14c2ba8a348abf6a05a7c52501d 100644
--- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
+++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
@@ -1878,7 +1878,7 @@ private ArrayTypeSymbol VisitArrayInitializer(BoundArrayCreation node)
(BoundExpression expressionNoConversion, Conversion conversion) = RemoveConversion(expression, includeExplicitConversions: false);
expressionsNoConversions.Add(expressionNoConversion);
conversions.Add(conversion);
- SnapshotWalkerThroughConversionGroup(expression as BoundConversion, expressionNoConversion);
+ SnapshotWalkerThroughConversionGroup(expression, expressionNoConversion);
var resultType = VisitRvalueWithState(expressionNoConversion);
resultTypes.Add(resultType);
placeholderBuilder.Add(CreatePlaceholderIfNecessary(expressionNoConversion, resultType.ToTypeWithAnnotations()));
@@ -2685,7 +2685,7 @@ public override BoundNode VisitConditionalOperator(BoundConditionalOperator node
BoundExpression operandNoConversion;
(operandNoConversion, conversion) = RemoveConversion(operand, includeExplicitConversions: false);
- SnapshotWalkerThroughConversionGroup(operand as BoundConversion, operandNoConversion);
+ SnapshotWalkerThroughConversionGroup(operand, operandNoConversion);
Visit(operandNoConversion);
return (operandNoConversion, conversion, ResultType);
}
@@ -3371,7 +3371,7 @@ void visitArgumentEvaluateAndUnsplit(int argumentIndex, bool assertsTrue, bool a
(argument, conversion) = RemoveConversion(argument, includeExplicitConversions: false);
if (argument != before)
{
- SnapshotWalkerThroughConversionGroup(before as BoundConversion, argument);
+ SnapshotWalkerThroughConversionGroup(before, argument);
includedConversion = true;
}
}
@@ -3875,7 +3875,7 @@ public override BoundNode VisitConversion(BoundConversion node)
Debug.Assert(targetType.HasType);
(BoundExpression operand, Conversion conversion) = RemoveConversion(node, includeExplicitConversions: true);
- SnapshotWalkerThroughConversionGroup(node as BoundConversion, operand);
+ SnapshotWalkerThroughConversionGroup(node, operand);
TypeWithState operandType = VisitRvalueWithState(operand);
SetResultType(node,
VisitConversion(
@@ -3909,7 +3909,7 @@ private TypeWithState VisitOptionalImplicitConversion(BoundExpression expr, Type
}
(BoundExpression operand, Conversion conversion) = RemoveConversion(expr, includeExplicitConversions: false);
- SnapshotWalkerThroughConversionGroup(expr as BoundConversion, operand);
+ SnapshotWalkerThroughConversionGroup(expr, operand);
var operandType = VisitRvalueWithState(operand);
// If an explicit conversion was used in place of an implicit conversion, the explicit
// conversion was created by initial binding after reporting "error CS0266:
@@ -4739,12 +4739,18 @@ static TypeWithState calculateResultType(TypeWithAnnotations targetTypeWithNulla
return operandType;
}
- private void SnapshotWalkerThroughConversionGroup(BoundConversion conversionOpt, BoundExpression convertedNode)
+ private void SnapshotWalkerThroughConversionGroup(BoundExpression conversionExpression, BoundExpression convertedNode)
{
+ if (_snapshotBuilderOpt is null)
+ {
+ return;
+ }
+
+ var conversionOpt = conversionExpression as BoundConversion;
var conversionGroup = conversionOpt?.ConversionGroupOpt;
while (conversionOpt != null &&
conversionOpt != convertedNode &&
- conversionOpt.Syntax.SpanStart != conversionOpt.Syntax.SpanStart)
+ conversionOpt.Syntax.SpanStart != convertedNode.Syntax.SpanStart)
{
Debug.Assert(conversionOpt.ConversionGroupOpt == conversionGroup);
TakeIncrementalSnapshot(conversionOpt);
@@ -5751,7 +5757,7 @@ protected override void VisitForEachExpression(BoundForEachStatement node)
}
var (expr, conversion) = RemoveConversion(node.Expression, includeExplicitConversions: false);
- SnapshotWalkerThroughConversionGroup(node.Expression as BoundConversion, expr);
+ SnapshotWalkerThroughConversionGroup(node.Expression, expr);
// There are 7 ways that a foreach can be created:
// 1. The collection type is an array type. For this, initial binding will generate an implicit reference conversion to
diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker_Patterns.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker_Patterns.cs
index c159ab6118ad994c04a38dfaaa9b0f3fe939f30e..dd07c63e354b8d74a68dabc77223d192f8de81fc 100644
--- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker_Patterns.cs
+++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker_Patterns.cs
@@ -503,10 +503,10 @@ public override BoundNode VisitSwitchExpression(BoundSwitchExpression node)
foreach (var arm in node.SwitchArms)
{
SetState(!arm.Pattern.HasErrors && labelStateMap.TryGetValue(arm.Label, out var labelState) ? labelState.state : UnreachableState());
- // https://github.com/dotnet/roslyn/issues/35836 Is this where we want to take the checkpoint?
+ // https://github.com/dotnet/roslyn/issues/35836 Is this where we want to take the snapshot?
TakeIncrementalSnapshot(arm);
(BoundExpression expression, Conversion conversion) = RemoveConversion(arm.Value, includeExplicitConversions: false);
- SnapshotWalkerThroughConversionGroup(arm.Value as BoundConversion, expression);
+ SnapshotWalkerThroughConversionGroup(arm.Value, expression);
expressions.Add(expression);
conversions.Add(conversion);
var armType = VisitRvalueWithState(expression);