dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
18.97k stars 4.03k forks source link

IndexOutOfRangeException when compiling type with 40 000 type constraints #38281

Open svick opened 5 years ago

svick commented 5 years ago

Version Used: .Net Core SDK 3.0.100-preview8-013656

Steps to Reproduce:

  1. Create a new project with the following code:

    using System.IO;
    
    class Program
    {
        static void Main()
        {
            int n = 40_000;
    
            using (var file = new StreamWriter("C.cs"))
            {
                file.WriteLine("using System.Collections.Generic;");
    
                file.Write("class C<");
                for (int i = 1; i < n; i++)
                    file.Write($"T{i}, ");
                file.Write($"T{n}");
                file.WriteLine(">");
    
                for (int i = 2; i <= n; i++)
                    file.WriteLine($"  where T{i} : List<T{i-1}>");
    
                file.WriteLine("{ }");
            }
        }
    }
  2. dotnet run to generate C.cs.
  3. dotnet build to compile C.cs.

Expected Behavior:

C.cs compiles.

Actual Behavior:

Unhandled exception. System.AggregateException: One or more errors occurred. (Index was outside the bounds of the array.)
 ---> System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Microsoft.CodeAnalysis.CSharp.Symbols.TypeParameterConstraintClause.<AdjustConstraintTypes>g__isValueType|8_0(TypeParameterSymbol thisTypeParameter, ArrayBuilder`1 constraintClauses, Dictionary`2 isValueTypeOverrideBuilder, ConsList`1 inProgress)
   at Microsoft.CodeAnalysis.CSharp.Symbols.TypeParameterConstraintClause.AdjustConstraintTypes(Symbol container, ImmutableArray`1 typeParameters, ArrayBuilder`1 constraintClauses, IReadOnlyDictionary`2& isValueTypeOverride)
   at Microsoft.CodeAnalysis.CSharp.Binder.BindTypeParameterConstraintClauses(Symbol containingSymbol, ImmutableArray`1 typeParameters, TypeParameterListSyntax typeParameterList, SyntaxList`1 clauses, IReadOnlyDictionary`2& isValueTypeOverride, DiagnosticBag diagnostics, Boolean isForOverride)
   at Microsoft.CodeAnalysis.CSharp.Symbols.SourceNamedTypeSymbol.MakeTypeParameterConstraints(DiagnosticBag diagnostics)
   at Microsoft.CodeAnalysis.CSharp.Symbols.SourceNamedTypeSymbol.GetTypeParameterConstraintClause(Int32 ordinal)
   at Microsoft.CodeAnalysis.CSharp.Symbols.SourceTypeParameterSymbol.ResolveBounds(ConsList`1 inProgress, DiagnosticBag diagnostics)
   at Microsoft.CodeAnalysis.CSharp.Symbols.SourceTypeParameterSymbolBase.GetBounds(ConsList`1 inProgress)
   at Microsoft.CodeAnalysis.CSharp.Symbols.SourceTypeParameterSymbolBase.GetConstraintTypes(ConsList`1 inProgress)
   at Microsoft.CodeAnalysis.CSharp.Symbols.TypeParameterSymbol.EnsureAllConstraintsAreResolved(ImmutableArray`1 typeParameters)
   at Microsoft.CodeAnalysis.CSharp.Symbols.SourceTypeParameterSymbolBase.EnsureAllConstraintsAreResolved()
   at Microsoft.CodeAnalysis.CSharp.Symbols.SourceTypeParameterSymbolBase.ForceComplete(SourceLocation locationOpt, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.CSharp.Symbols.SourceMemberContainerTypeSymbol.ForceComplete(SourceLocation locationOpt, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.CSharp.Symbol.ForceCompleteMemberByLocation(SourceLocation locationOpt, Symbol member, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.CSharp.Symbols.SourceNamespaceSymbol.<>c__DisplayClass49_1.<ForceComplete>b__0(Int32 i)
   at Roslyn.Utilities.UICultureUtilities.<>c__DisplayClass6_0`1.<WithCurrentUICulture>b__0(T param)
   at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`1.<ForWorker>b__1(RangeWorker& currentWorker, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(Exception source)
   at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`1.<ForWorker>b__1(RangeWorker& currentWorker, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
   at System.Threading.Tasks.TaskReplicator.Replica`1.ExecuteAction(Boolean& yieldedBeforeCompletion) 
   at System.Threading.Tasks.TaskReplicator.Replica.Execute() [C:\code\tmp\hwapp\hwapp.csproj]        
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.TaskReplicator.Run[TState](ReplicatableUserAction`1 action, ParallelOptions options, Boolean stopOnFirstFailure)
   at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(Exception source)
   at System.Threading.Tasks.Parallel.ThrowSingleCancellationExceptionOrOtherException(ICollection exceptions, CancellationToken cancelToken, Exception otherException)
   at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
   at System.Threading.Tasks.Parallel.For(Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body)
   at Microsoft.CodeAnalysis.CSharp.Symbols.SourceNamespaceSymbol.ForceComplete(SourceLocation locationOpt, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.CSharp.Symbols.SourceModuleSymbol.ForceComplete(SourceLocation locationOpt, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.CSharp.CommandLine.Csc.<>c__DisplayClass1_0.<Run>b__0(TextWriter tw)
   at Microsoft.CodeAnalysis.CommandLine.ConsoleUtil.RunWithUtf8Output[T](Func`2 func)
   at Microsoft.CodeAnalysis.CommandLine.ConsoleUtil.RunWithUtf8Output[T](Boolean utf8Output, TextWriter textWriter, Func`2 func)
   at Microsoft.CodeAnalysis.CSharp.CommandLine.Csc.Run(String[] args, BuildPaths buildPaths, TextWriter textWriter, IAnalyzerAssemblyLoader analyzerLoader)
   at Microsoft.CodeAnalysis.CommandLine.DesktopBuildClient.RunLocalCompilation(String[] arguments, BuildPaths buildPaths, TextWriter textWriter)
   at Microsoft.CodeAnalysis.CommandLine.BuildClient.RunCompilation(IEnumerable`1 originalArguments, BuildPaths buildPaths, TextWriter textWriter)
   at Microsoft.CodeAnalysis.CommandLine.DesktopBuildClient.Run(IEnumerable`1 arguments, RequestLanguage language, CompileFunc compileFunc, IAnalyzerAssemblyLoader analyzerAssemblyLoader)
   at Microsoft.CodeAnalysis.CSharp.CommandLine.Program.MainCore(String[] args)
   at Microsoft.CodeAnalysis.CSharp.CommandLine.Program.Main(String[] args)

Note that I encountered this while investigating https://github.com/dotnet/roslyn/issues/38279, but this issue is almost certainly unrelated to that one. This means that, AFAIK, no actual user code is experiencing this exception, so fixing it is likely going to be low priority.

CyrusNajmabadi commented 5 years ago

Have you considered using less constraints? :)

gafter commented 5 years ago

https://www.dictionary.com/e/fewer-vs-less/