Addressed PR feedback.

上级 14f7bfd0
......@@ -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();
......
......@@ -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);
......
......@@ -14,7 +14,7 @@ internal sealed partial class NullableWalker
internal sealed class SnapshotManager
{
/// <summary>
/// The int key corresponds to <see cref="Snapshot.GlobalStateIndex"/>.
/// The int key corresponds to <see cref="Snapshot.SharedStateIndex"/>.
/// </summary>
private readonly ImmutableArray<SharedWalkerState> _walkerGlobalStates;
/// <summary>
......@@ -53,7 +53,7 @@ private SnapshotManager(ImmutableArray<SharedWalkerState> 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)
/// </summary>
private sealed class DescendingIntComparer : IComparer<int>
{
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
/// <summary>
/// Snapshots are kept in a dictionary of position -> snapshot at that position. These are stored in descending order.
/// </summary>
private readonly ImmutableSortedDictionary<int, Snapshot>.Builder _incrementalSnapshots = ImmutableSortedDictionary.CreateBuilder<int, Snapshot>(new DescendingIntComparer());
private readonly ImmutableSortedDictionary<int, Snapshot>.Builder _incrementalSnapshots = ImmutableSortedDictionary.CreateBuilder<int, Snapshot>(DescendingIntComparer.Singleton);
/// <summary>
/// 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)
}
/// <summary>
/// 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
/// </summary>
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;
}
}
}
......
......@@ -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
......
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册