未验证 提交 4e5a2294 编写于 作者: C Charles Stoner 提交者: GitHub

Reduce stack frame size of CheckConstraints (#43094)

上级 9e21d4d1
......@@ -495,7 +495,7 @@ NamespaceOrTypeOrAliasSymbolWithAnnotations bindNullable()
ReportUseSiteDiagnostics(constructedType.Type.OriginalDefinition, diagnostics, syntax);
var type = (NamedTypeSymbol)constructedType.Type;
var location = syntax.Location;
type.CheckConstraints(this.Compilation, this.Conversions, includeNullability: true, location, diagnostics);
type.CheckConstraints(new ConstraintsHelper.CheckConstraintsArgs(this.Compilation, this.Conversions, includeNullability: true, location, diagnostics));
}
else if (constructedType.Type.IsTypeParameterDisallowingAnnotation())
{
......
......@@ -386,7 +386,6 @@ private bool FailsConstraintChecks(MethodSymbol method, out ArrayBuilder<TypePar
bool constraintsSatisfied = ConstraintsHelper.CheckMethodConstraints(
method,
this.Conversions,
includeNullability: false,
this.Compilation,
diagnosticsBuilder,
nullabilityDiagnosticsBuilderOpt: null,
......
......@@ -981,7 +981,7 @@ private void ReportDuplicateNamedArgument(MemberResolutionResult<TMember> result
// formal parameter type.
TypeSymbol formalParameterType = method.GetParameterType(result.Result.BadParameter);
formalParameterType.CheckAllConstraints((CSharpCompilation)compilation, conversions, includeNullability: false, location, diagnostics);
formalParameterType.CheckAllConstraints(new ConstraintsHelper.CheckConstraintsArgs((CSharpCompilation)compilation, conversions, includeNullability: false, location, diagnostics));
return true;
}
......
......@@ -5354,7 +5354,6 @@ private void CheckMethodConstraints(SyntaxNode syntax, MethodSymbol method)
ConstraintsHelper.CheckMethodConstraints(
method,
_conversions,
includeNullability: true,
compilation,
diagnosticsBuilder,
nullabilityBuilder,
......@@ -5719,7 +5718,7 @@ private void VisitTupleExpression(BoundTupleExpression node)
if (!_disableDiagnostics)
{
var locations = tupleOpt.TupleElements.SelectAsArray((element, location) => element.Locations.FirstOrDefault() ?? location, node.Syntax.Location);
tupleOpt.CheckConstraints(_conversions, includeNullability: true, typeSyntax: node.Syntax, locations, currentCompilation: compilation, diagnosticsOpt: null, nullabilityDiagnosticsOpt: Diagnostics);
tupleOpt.CheckConstraints(_conversions, typeSyntax: node.Syntax, locations, currentCompilation: compilation, diagnosticsOpt: null, nullabilityDiagnosticsOpt: Diagnostics);
}
SetResultType(node, TypeWithState.Create(tupleOpt, NullableFlowState.NotNull));
......
......@@ -198,7 +198,7 @@ private static MethodSymbol InferExtensionMethodTypeArguments(MethodSymbol metho
var diagnosticsBuilder = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
var substitution = new TypeMap(typeParams, typeArgsForConstraintsCheck);
ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
var success = method.CheckConstraints(conversions, includeNullability: false, substitution, typeParams, typeArgsForConstraintsCheck, compilation, diagnosticsBuilder, nullabilityDiagnosticsBuilderOpt: null, ref useSiteDiagnosticsBuilder,
var success = method.CheckConstraints(conversions, substitution, typeParams, typeArgsForConstraintsCheck, compilation, diagnosticsBuilder, nullabilityDiagnosticsBuilderOpt: null, ref useSiteDiagnosticsBuilder,
ignoreTypeConstraintsDependentOnTypeParametersOpt: notInferredTypeParameters.Count > 0 ? notInferredTypeParameters : null);
diagnosticsBuilder.Free();
notInferredTypeParameters.Free();
......
......@@ -256,18 +256,15 @@ private void CheckConstraintTypeConstraints(DiagnosticBag diagnostics)
return;
}
var corLibrary = this.ContainingAssembly.CorLibrary;
var conversions = new TypeConversions(corLibrary);
var location = _locations[0];
var args = new ConstraintsHelper.CheckConstraintsArgs(DeclaringCompilation, new TypeConversions(ContainingAssembly.CorLibrary), _locations[0], diagnostics);
foreach (var constraintType in constraintTypes)
{
HashSet<DiagnosticInfo> useSiteDiagnostics = null;
constraintType.Type.AddUseSiteDiagnostics(ref useSiteDiagnostics);
if (!diagnostics.Add(location, useSiteDiagnostics))
if (!diagnostics.Add(args.Location, useSiteDiagnostics))
{
constraintType.Type.CheckAllConstraints(DeclaringCompilation, conversions, location, diagnostics);
constraintType.Type.CheckAllConstraints(args);
}
}
}
......
......@@ -67,7 +67,7 @@ internal abstract partial class NamedTypeSymbol
var constructedType = CreateTuple(underlyingType, elementNames, errorPositions, elementLocations, locations);
if (shouldCheckConstraints && diagnostics != null)
{
constructedType.CheckConstraints(compilation.Conversions, includeNullability, syntax, elementLocations, compilation, diagnostics, diagnostics);
constructedType.CheckConstraints(compilation.Conversions, syntax, elementLocations, compilation, diagnosticsOpt: diagnostics, nullabilityDiagnosticsOpt: includeNullability ? diagnostics : null);
}
return constructedType;
......
......@@ -8,6 +8,8 @@
using Xunit;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.PooledObjects;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Emit
{
......@@ -267,5 +269,48 @@ static void Main()
});
}
}
[WorkItem(42361, "https://github.com/dotnet/roslyn/issues/42361")]
[ConditionalFact(typeof(WindowsOnly))]
public void Constraints()
{
int n = (ExecutionConditionUtil.Architecture, ExecutionConditionUtil.Configuration) switch
{
(ExecutionArchitecture.x86, ExecutionConfiguration.Debug) => 420,
(ExecutionArchitecture.x86, ExecutionConfiguration.Release) => 1100,
(ExecutionArchitecture.x64, ExecutionConfiguration.Debug) => 200,
(ExecutionArchitecture.x64, ExecutionConfiguration.Release) => 520,
_ => throw new Exception($"Unexpected configuration {ExecutionConditionUtil.Architecture} {ExecutionConditionUtil.Configuration}")
};
RunTest(n, runTest);
static void runTest(int n)
{
// class C0<T> where T : C1<T> { }
// class C1<T> where T : C2<T> { }
// ...
// class CN<T> where T : C0<T> { }
var sourceBuilder = new StringBuilder();
var diagnosticsBuilder = ArrayBuilder<DiagnosticDescription>.GetInstance();
for (int i = 0; i <= n; i++)
{
int next = (i == n) ? 0 : i + 1;
sourceBuilder.AppendLine($"class C{i}<T> where T : C{next}<T> {{ }}");
diagnosticsBuilder.Add(Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedRefType, "T").WithArguments($"C{i}<T>", $"C{next}<T>", "T", "T"));
}
var source = sourceBuilder.ToString();
var diagnostics = diagnosticsBuilder.ToArrayAndFree();
RunInThread(() =>
{
var comp = CreateCompilation(source);
var type = comp.GetMember<NamedTypeSymbol>("C0");
var typeParameter = type.TypeParameters[0];
Assert.True(typeParameter.IsReferenceType);
comp.VerifyDiagnostics(diagnostics);
});
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册