1200 lines
57 KiB
C#
1200 lines
57 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Runtime.CompilerServices;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Microsoft.CodeAnalysis.PooledObjects;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp.Symbols;
|
|
|
|
internal static class ConstraintsHelper
|
|
{
|
|
internal readonly struct CheckConstraintsArgs
|
|
{
|
|
public readonly CSharpCompilation CurrentCompilation;
|
|
|
|
public readonly ConversionsBase Conversions;
|
|
|
|
public readonly bool IncludeNullability;
|
|
|
|
public readonly Location Location;
|
|
|
|
public readonly BindingDiagnosticBag Diagnostics;
|
|
|
|
public readonly CompoundUseSiteInfo<AssemblySymbol> Template;
|
|
|
|
public CheckConstraintsArgs(CSharpCompilation currentCompilation, ConversionsBase conversions, Location location, BindingDiagnosticBag diagnostics)
|
|
: this(currentCompilation, conversions, currentCompilation.IsFeatureEnabled(MessageID.IDS_FeatureNullableReferenceTypes), location, diagnostics)
|
|
{
|
|
}
|
|
|
|
public CheckConstraintsArgs(CSharpCompilation currentCompilation, ConversionsBase conversions, bool includeNullability, Location location, BindingDiagnosticBag diagnostics)
|
|
: this(currentCompilation, conversions, includeNullability, location, diagnostics, new CompoundUseSiteInfo<AssemblySymbol>((BindingDiagnosticBag<AssemblySymbol>)(object)diagnostics, currentCompilation.Assembly))
|
|
{
|
|
}//IL_0010: Unknown result type (might be due to invalid IL or missing references)
|
|
|
|
|
|
public CheckConstraintsArgs(CSharpCompilation currentCompilation, ConversionsBase conversions, bool includeNullability, Location location, BindingDiagnosticBag diagnostics, CompoundUseSiteInfo<AssemblySymbol> template)
|
|
{
|
|
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
|
|
CurrentCompilation = currentCompilation;
|
|
Conversions = conversions;
|
|
IncludeNullability = includeNullability;
|
|
Location = location;
|
|
Diagnostics = diagnostics;
|
|
Template = template;
|
|
}
|
|
}
|
|
|
|
internal sealed class CheckConstraintsArgsBoxed
|
|
{
|
|
public CheckConstraintsArgs Args;
|
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
|
public static CheckConstraintsArgsBoxed Allocate(CSharpCompilation currentCompilation, ConversionsBase conversions, Location location, BindingDiagnosticBag diagnostics)
|
|
{
|
|
CheckConstraintsArgsBoxed checkConstraintsArgsBoxed = s_checkConstraintsArgsBoxedPool.Allocate();
|
|
checkConstraintsArgsBoxed.Args = new CheckConstraintsArgs(currentCompilation, conversions, location, diagnostics);
|
|
return checkConstraintsArgsBoxed;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
|
public static CheckConstraintsArgsBoxed Allocate(CSharpCompilation currentCompilation, ConversionsBase conversions, bool includeNullability, Location location, BindingDiagnosticBag diagnostics)
|
|
{
|
|
CheckConstraintsArgsBoxed checkConstraintsArgsBoxed = s_checkConstraintsArgsBoxedPool.Allocate();
|
|
checkConstraintsArgsBoxed.Args = new CheckConstraintsArgs(currentCompilation, conversions, includeNullability, location, diagnostics);
|
|
return checkConstraintsArgsBoxed;
|
|
}
|
|
|
|
public void Free()
|
|
{
|
|
Args = default(CheckConstraintsArgs);
|
|
s_checkConstraintsArgsBoxedPool.Free(this);
|
|
}
|
|
}
|
|
|
|
private enum ConstructorConstraintError
|
|
{
|
|
None,
|
|
NoPublicParameterlessConstructorOrAbstractType,
|
|
HasRequiredMembers
|
|
}
|
|
|
|
private static readonly ObjectPool<CheckConstraintsArgsBoxed> s_checkConstraintsArgsBoxedPool = new ObjectPool<CheckConstraintsArgsBoxed>((Factory<CheckConstraintsArgsBoxed>)(() => new CheckConstraintsArgsBoxed()), true);
|
|
|
|
private static readonly Func<TypeSymbol, CheckConstraintsArgsBoxed, bool, bool> s_checkConstraintsSingleTypeFunc = (TypeSymbol type, CheckConstraintsArgsBoxed arg, bool unused) => CheckConstraintsSingleType(type, in arg.Args);
|
|
|
|
public static TypeParameterBounds ResolveBounds(this TypeParameterSymbol typeParameter, AssemblySymbol corLibrary, ConsList<TypeParameterSymbol> inProgress, ImmutableArray<TypeWithAnnotations> constraintTypes, bool inherited, CSharpCompilation currentCompilation, BindingDiagnosticBag diagnostics)
|
|
{
|
|
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
|
|
ArrayBuilder<TypeParameterDiagnosticInfo> instance = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
|
|
ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
|
|
TypeParameterBounds result = typeParameter.ResolveBounds(corLibrary, inProgress, constraintTypes, inherited, currentCompilation, instance, ref useSiteDiagnosticsBuilder, new CompoundUseSiteInfo<AssemblySymbol>((BindingDiagnosticBag<AssemblySymbol>)(object)diagnostics, currentCompilation.Assembly));
|
|
if (useSiteDiagnosticsBuilder != null)
|
|
{
|
|
instance.AddRange(useSiteDiagnosticsBuilder);
|
|
}
|
|
Enumerator<TypeParameterDiagnosticInfo> enumerator = instance.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
TypeParameterDiagnosticInfo current = enumerator.Current;
|
|
((BindingDiagnosticBag<AssemblySymbol>)(object)diagnostics).Add(current.UseSiteInfo, current.TypeParameter.GetFirstLocation());
|
|
}
|
|
instance.Free();
|
|
return result;
|
|
}
|
|
|
|
public static TypeParameterBounds ResolveBounds(this TypeParameterSymbol typeParameter, AssemblySymbol corLibrary, ConsList<TypeParameterSymbol> inProgress, ImmutableArray<TypeWithAnnotations> constraintTypes, bool inherited, CSharpCompilation currentCompilation, ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder, ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder, CompoundUseSiteInfo<AssemblySymbol> template)
|
|
{
|
|
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00a5: Expected I4, but got Unknown
|
|
//IL_034d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0373: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0379: Invalid comparison between Unknown and I4
|
|
//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_020b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0212: Invalid comparison between Unknown and I4
|
|
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0258: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_032a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0193: Unknown result type (might be due to invalid IL or missing references)
|
|
NamedTypeSymbol namedTypeSymbol = corLibrary.GetSpecialType((SpecialType)((!typeParameter.HasValueTypeConstraint) ? 1 : 5));
|
|
TypeSymbol typeSymbol = namedTypeSymbol;
|
|
ImmutableArray<NamedTypeSymbol> interfaces;
|
|
if (constraintTypes.Length == 0)
|
|
{
|
|
interfaces = ImmutableArray<NamedTypeSymbol>.Empty;
|
|
}
|
|
else
|
|
{
|
|
ArrayBuilder<TypeWithAnnotations> instance = ArrayBuilder<TypeWithAnnotations>.GetInstance();
|
|
ArrayBuilder<NamedTypeSymbol> instance2 = ArrayBuilder<NamedTypeSymbol>.GetInstance();
|
|
TypeConversions typeConversions = corLibrary.TypeConversions;
|
|
CompoundUseSiteInfo<AssemblySymbol> useSiteInfo = default(CompoundUseSiteInfo<AssemblySymbol>);
|
|
useSiteInfo._002Ector(template);
|
|
ImmutableArray<TypeWithAnnotations>.Enumerator enumerator = constraintTypes.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
TypeWithAnnotations current = enumerator.Current;
|
|
TypeKind typeKind = current.TypeKind;
|
|
NamedTypeSymbol namedTypeSymbol2;
|
|
TypeSymbol typeSymbol2;
|
|
switch (typeKind - 1)
|
|
{
|
|
case 10:
|
|
{
|
|
TypeParameterSymbol typeParameterSymbol2 = (TypeParameterSymbol)current.Type;
|
|
ConsList<TypeParameterSymbol> inProgress2;
|
|
if (typeParameterSymbol2.ContainingSymbol == typeParameter.ContainingSymbol)
|
|
{
|
|
if (ConsListExtensions.ContainsReference<TypeParameterSymbol>(inProgress, typeParameterSymbol2))
|
|
{
|
|
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameterSymbol2, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_CircularConstraint, typeParameterSymbol2, typeParameter))));
|
|
continue;
|
|
}
|
|
inProgress2 = inProgress;
|
|
}
|
|
else
|
|
{
|
|
inProgress2 = ConsList<TypeParameterSymbol>.Empty;
|
|
}
|
|
namedTypeSymbol2 = typeParameterSymbol2.GetEffectiveBaseClass(inProgress2);
|
|
typeSymbol2 = typeParameterSymbol2.GetDeducedBaseType(inProgress2);
|
|
AddInterfaces(instance2, typeParameterSymbol2.GetInterfaces(inProgress2));
|
|
if (inherited || currentCompilation == null || !typeParameterSymbol2.IsFromCompilation(currentCompilation))
|
|
{
|
|
break;
|
|
}
|
|
ErrorCode code;
|
|
if (typeParameterSymbol2.HasUnmanagedTypeConstraint)
|
|
{
|
|
code = ErrorCode.ERR_ConWithUnmanagedCon;
|
|
}
|
|
else
|
|
{
|
|
if (!typeParameterSymbol2.HasValueTypeConstraint)
|
|
{
|
|
break;
|
|
}
|
|
code = ErrorCode.ERR_ConWithValCon;
|
|
}
|
|
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(code, typeParameter, typeParameterSymbol2))));
|
|
continue;
|
|
}
|
|
case 1:
|
|
case 2:
|
|
case 6:
|
|
if (current.Type.IsInterfaceType())
|
|
{
|
|
AddInterface(instance2, (NamedTypeSymbol)current.Type);
|
|
instance.Add(current);
|
|
continue;
|
|
}
|
|
namedTypeSymbol2 = (NamedTypeSymbol)current.Type;
|
|
typeSymbol2 = current.Type;
|
|
break;
|
|
case 9:
|
|
if (current.IsNullableType())
|
|
{
|
|
TypeSymbol nullableUnderlyingType = current.Type.GetNullableUnderlyingType();
|
|
if ((int)nullableUnderlyingType.TypeKind == 11)
|
|
{
|
|
TypeParameterSymbol typeParameterSymbol = (TypeParameterSymbol)nullableUnderlyingType;
|
|
if (typeParameterSymbol.ContainingSymbol == typeParameter.ContainingSymbol && ConsListExtensions.ContainsReference<TypeParameterSymbol>(inProgress, typeParameterSymbol))
|
|
{
|
|
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameterSymbol, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_CircularConstraint, typeParameterSymbol, typeParameter))));
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
namedTypeSymbol2 = corLibrary.GetSpecialType((SpecialType)5);
|
|
typeSymbol2 = current.Type;
|
|
break;
|
|
case 4:
|
|
namedTypeSymbol2 = corLibrary.GetSpecialType((SpecialType)2);
|
|
typeSymbol2 = current.Type;
|
|
break;
|
|
case 0:
|
|
namedTypeSymbol2 = corLibrary.GetSpecialType((SpecialType)23);
|
|
typeSymbol2 = current.Type;
|
|
break;
|
|
case 5:
|
|
namedTypeSymbol2 = (NamedTypeSymbol)current.Type;
|
|
typeSymbol2 = current.Type;
|
|
break;
|
|
default:
|
|
throw ExceptionUtilities.UnexpectedValue((object)current.TypeKind);
|
|
case 8:
|
|
case 12:
|
|
continue;
|
|
}
|
|
instance.Add(current);
|
|
if (!typeSymbol.IsErrorType() && !typeSymbol2.IsErrorType() && !IsEncompassedBy(typeConversions, typeSymbol, typeSymbol2, ref useSiteInfo))
|
|
{
|
|
if (!IsEncompassedBy(typeConversions, typeSymbol2, typeSymbol, ref useSiteInfo))
|
|
{
|
|
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_BaseConstraintConflict, typeParameter, typeSymbol2, typeSymbol))));
|
|
}
|
|
else
|
|
{
|
|
typeSymbol = typeSymbol2;
|
|
namedTypeSymbol = namedTypeSymbol2;
|
|
}
|
|
}
|
|
}
|
|
AppendUseSiteDiagnostics(useSiteInfo, typeParameter, ref useSiteDiagnosticsBuilder);
|
|
constraintTypes = instance.ToImmutableAndFree();
|
|
interfaces = instance2.ToImmutableAndFree();
|
|
}
|
|
if (constraintTypes.Length == 0 && (int)typeSymbol.SpecialType == 1)
|
|
{
|
|
return null;
|
|
}
|
|
TypeParameterBounds typeParameterBounds = new TypeParameterBounds(constraintTypes, interfaces, namedTypeSymbol, typeSymbol);
|
|
if (inherited)
|
|
{
|
|
CheckOverrideConstraints(typeParameter, typeParameterBounds, diagnosticsBuilder);
|
|
}
|
|
return typeParameterBounds;
|
|
}
|
|
|
|
internal static ImmutableArray<ImmutableArray<TypeWithAnnotations>> MakeTypeParameterConstraintTypes(this MethodSymbol containingSymbol, Binder withTypeParametersBinder, ImmutableArray<TypeParameterSymbol> typeParameters, TypeParameterListSyntax typeParameterList, SyntaxList<TypeParameterConstraintClauseSyntax> constraintClauses, BindingDiagnosticBag diagnostics)
|
|
{
|
|
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
|
|
if (typeParameters.Length == 0 || constraintClauses.Count == 0)
|
|
{
|
|
return ImmutableArray<ImmutableArray<TypeWithAnnotations>>.Empty;
|
|
}
|
|
withTypeParametersBinder = withTypeParametersBinder.WithAdditionalFlags(BinderFlags.SuppressConstraintChecks | BinderFlags.GenericConstraintsClause);
|
|
ImmutableArray<TypeParameterConstraintClause> immutableArray = withTypeParametersBinder.BindTypeParameterConstraintClauses(containingSymbol, typeParameters, typeParameterList, constraintClauses, diagnostics, performOnlyCycleSafeValidation: false);
|
|
if (immutableArray.All((TypeParameterConstraintClause clause) => clause.ConstraintTypes.IsEmpty))
|
|
{
|
|
return ImmutableArray<ImmutableArray<TypeWithAnnotations>>.Empty;
|
|
}
|
|
return ImmutableArrayExtensions.SelectAsArray<TypeParameterConstraintClause, ImmutableArray<TypeWithAnnotations>>(immutableArray, (Func<TypeParameterConstraintClause, ImmutableArray<TypeWithAnnotations>>)((TypeParameterConstraintClause clause) => clause.ConstraintTypes));
|
|
}
|
|
|
|
internal static ImmutableArray<TypeParameterConstraintKind> MakeTypeParameterConstraintKinds(this MethodSymbol containingSymbol, Binder withTypeParametersBinder, ImmutableArray<TypeParameterSymbol> typeParameters, TypeParameterListSyntax typeParameterList, SyntaxList<TypeParameterConstraintClauseSyntax> constraintClauses)
|
|
{
|
|
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
|
|
if (typeParameters.Length == 0)
|
|
{
|
|
return ImmutableArray<TypeParameterConstraintKind>.Empty;
|
|
}
|
|
ImmutableArray<TypeParameterConstraintClause> immutableArray;
|
|
if (constraintClauses.Count == 0)
|
|
{
|
|
immutableArray = withTypeParametersBinder.GetDefaultTypeParameterConstraintClauses(typeParameterList);
|
|
}
|
|
else
|
|
{
|
|
withTypeParametersBinder = withTypeParametersBinder.WithAdditionalFlags(BinderFlags.SuppressConstraintChecks | BinderFlags.GenericConstraintsClause | BinderFlags.SuppressTypeArgumentBinding);
|
|
immutableArray = withTypeParametersBinder.BindTypeParameterConstraintClauses(containingSymbol, typeParameters, typeParameterList, constraintClauses, BindingDiagnosticBag.Discarded, performOnlyCycleSafeValidation: true);
|
|
immutableArray = AdjustConstraintKindsBasedOnConstraintTypes(typeParameters, immutableArray);
|
|
}
|
|
if (immutableArray.All((TypeParameterConstraintClause clause) => clause.Constraints == TypeParameterConstraintKind.None))
|
|
{
|
|
return ImmutableArray<TypeParameterConstraintKind>.Empty;
|
|
}
|
|
return ImmutableArrayExtensions.SelectAsArray<TypeParameterConstraintClause, TypeParameterConstraintKind>(immutableArray, (Func<TypeParameterConstraintClause, TypeParameterConstraintKind>)((TypeParameterConstraintClause clause) => clause.Constraints));
|
|
}
|
|
|
|
internal static ImmutableArray<TypeParameterConstraintClause> AdjustConstraintKindsBasedOnConstraintTypes(ImmutableArray<TypeParameterSymbol> typeParameters, ImmutableArray<TypeParameterConstraintClause> constraintClauses)
|
|
{
|
|
int length = typeParameters.Length;
|
|
SmallDictionary<TypeParameterSymbol, bool> val = TypeParameterConstraintClause.BuildIsValueTypeMap(typeParameters, constraintClauses);
|
|
SmallDictionary<TypeParameterSymbol, bool> val2 = TypeParameterConstraintClause.BuildIsReferenceTypeFromConstraintTypesMap(typeParameters, constraintClauses);
|
|
ArrayBuilder<TypeParameterConstraintClause> val3 = null;
|
|
for (int i = 0; i < length; i++)
|
|
{
|
|
TypeParameterConstraintClause typeParameterConstraintClause = constraintClauses[i];
|
|
TypeParameterSymbol typeParameterSymbol = typeParameters[i];
|
|
TypeParameterConstraintKind typeParameterConstraintKind = typeParameterConstraintClause.Constraints;
|
|
if ((typeParameterConstraintKind & TypeParameterConstraintKind.AllValueTypeKinds) == 0 && val[typeParameterSymbol])
|
|
{
|
|
typeParameterConstraintKind |= TypeParameterConstraintKind.ValueTypeFromConstraintTypes;
|
|
}
|
|
if (val2[typeParameterSymbol])
|
|
{
|
|
typeParameterConstraintKind |= TypeParameterConstraintKind.ReferenceTypeFromConstraintTypes;
|
|
}
|
|
if (typeParameterConstraintClause.Constraints != typeParameterConstraintKind)
|
|
{
|
|
if (val3 == null)
|
|
{
|
|
val3 = ArrayBuilder<TypeParameterConstraintClause>.GetInstance(constraintClauses.Length);
|
|
val3.AddRange(constraintClauses);
|
|
}
|
|
val3[i] = TypeParameterConstraintClause.Create(typeParameterConstraintKind, typeParameterConstraintClause.ConstraintTypes);
|
|
}
|
|
}
|
|
if (val3 != null)
|
|
{
|
|
constraintClauses = val3.ToImmutableAndFree();
|
|
}
|
|
return constraintClauses;
|
|
}
|
|
|
|
private static void CheckOverrideConstraints(TypeParameterSymbol typeParameter, TypeParameterBounds bounds, ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder)
|
|
{
|
|
TypeSymbol deducedBaseType = bounds.DeducedBaseType;
|
|
ImmutableArray<TypeWithAnnotations> constraintTypes = bounds.ConstraintTypes;
|
|
if (IsValueType(typeParameter, constraintTypes) && IsReferenceType(typeParameter, constraintTypes))
|
|
{
|
|
diagnosticsBuilder.Add(GenerateConflictingConstraintsError(typeParameter, deducedBaseType, deducedBaseType.IsValueType));
|
|
}
|
|
else if (deducedBaseType.IsNullableType() && (typeParameter.HasValueTypeConstraint || typeParameter.HasReferenceTypeConstraint))
|
|
{
|
|
diagnosticsBuilder.Add(GenerateConflictingConstraintsError(typeParameter, deducedBaseType, typeParameter.HasReferenceTypeConstraint));
|
|
}
|
|
}
|
|
|
|
public static void CheckAllConstraints(this TypeSymbol type, CSharpCompilation compilation, ConversionsBase conversions, Location location, BindingDiagnosticBag diagnostics)
|
|
{
|
|
bool includeNullability = compilation.IsFeatureEnabled(MessageID.IDS_FeatureNullableReferenceTypes);
|
|
CheckConstraintsArgsBoxed checkConstraintsArgsBoxed = CheckConstraintsArgsBoxed.Allocate(compilation, conversions, includeNullability, location, diagnostics);
|
|
type.CheckAllConstraints(checkConstraintsArgsBoxed);
|
|
checkConstraintsArgsBoxed.Free();
|
|
}
|
|
|
|
public static bool CheckAllConstraints(this TypeSymbol type, CSharpCompilation compilation, ConversionsBase conversions)
|
|
{
|
|
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance(withDiagnostics: true, withDependencies: false);
|
|
CheckConstraintsArgsBoxed checkConstraintsArgsBoxed = CheckConstraintsArgsBoxed.Allocate(compilation, conversions, includeNullability: false, NoLocation.Singleton, instance);
|
|
type.CheckAllConstraints(checkConstraintsArgsBoxed);
|
|
bool result = !((BindingDiagnosticBag)instance).HasAnyErrors();
|
|
checkConstraintsArgsBoxed.Free();
|
|
((BindingDiagnosticBag<AssemblySymbol>)(object)instance).Free();
|
|
return result;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static void CheckAllConstraints(this TypeSymbol type, CheckConstraintsArgsBoxed args)
|
|
{
|
|
type.VisitType(s_checkConstraintsSingleTypeFunc, args);
|
|
}
|
|
|
|
private static bool CheckConstraintsSingleType(TypeSymbol type, in CheckConstraintsArgs args)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0008: Invalid comparison between Unknown and I4
|
|
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0021: Invalid comparison between Unknown and I4
|
|
if ((int)type.Kind == 11)
|
|
{
|
|
((NamedTypeSymbol)type).CheckConstraints(in args);
|
|
}
|
|
else if ((int)type.Kind == 14)
|
|
{
|
|
Binder.CheckManagedAddr(args.CurrentCompilation, ((PointerTypeSymbol)type).PointedAtType, args.Location, args.Diagnostics);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static void CheckConstraints(this NamedTypeSymbol tuple, in CheckConstraintsArgs args, SyntaxNode typeSyntax, ImmutableArray<Location> elementLocations, BindingDiagnosticBag nullabilityDiagnosticsOpt)
|
|
{
|
|
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!RequiresChecking(tuple) || typeSyntax.HasErrors)
|
|
{
|
|
return;
|
|
}
|
|
ArrayBuilder<TypeParameterDiagnosticInfo> instance = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
|
|
ArrayBuilder<TypeParameterDiagnosticInfo> instance2 = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
|
|
ArrayBuilder<NamedTypeSymbol> instance3 = ArrayBuilder<NamedTypeSymbol>.GetInstance();
|
|
NamedTypeSymbol.GetUnderlyingTypeChain(tuple, instance3);
|
|
int offset = 0;
|
|
Enumerator<NamedTypeSymbol> enumerator = instance3.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
NamedTypeSymbol current = enumerator.Current;
|
|
ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
|
|
CheckTypeConstraints(current, in args, instance, (nullabilityDiagnosticsOpt == null) ? null : instance2, ref useSiteDiagnosticsBuilder);
|
|
if (useSiteDiagnosticsBuilder != null)
|
|
{
|
|
instance.AddRange(useSiteDiagnosticsBuilder);
|
|
}
|
|
populateDiagnosticsAndClear(instance, args.Diagnostics);
|
|
populateDiagnosticsAndClear(instance2, nullabilityDiagnosticsOpt);
|
|
offset += 7;
|
|
}
|
|
instance3.Free();
|
|
instance.Free();
|
|
instance2.Free();
|
|
void populateDiagnosticsAndClear(ArrayBuilder<TypeParameterDiagnosticInfo> builder, BindingDiagnosticBag bag)
|
|
{
|
|
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
|
|
if (bag == null)
|
|
{
|
|
builder.Clear();
|
|
}
|
|
else
|
|
{
|
|
Enumerator<TypeParameterDiagnosticInfo> enumerator2 = builder.GetEnumerator();
|
|
while (enumerator2.MoveNext())
|
|
{
|
|
TypeParameterDiagnosticInfo current2 = enumerator2.Current;
|
|
int ordinal = current2.TypeParameter.Ordinal;
|
|
Location val = ((ordinal == 7) ? typeSyntax.Location : elementLocations[ordinal + offset]);
|
|
((BindingDiagnosticBag<AssemblySymbol>)(object)bag).Add(current2.UseSiteInfo, val);
|
|
}
|
|
builder.Clear();
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool CheckConstraintsForNamedType(this NamedTypeSymbol type, in CheckConstraintsArgs args, SyntaxNode typeSyntax, SeparatedSyntaxList<TypeSyntax> typeArgumentsSyntax, ConsList<TypeSymbol> basesBeingResolved)
|
|
{
|
|
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!RequiresChecking(type))
|
|
{
|
|
return true;
|
|
}
|
|
ArrayBuilder<TypeParameterDiagnosticInfo> instance = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
|
|
ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
|
|
bool result = !typeSyntax.HasErrors && CheckTypeConstraints(type, in args, instance, args.IncludeNullability ? instance : null, ref useSiteDiagnosticsBuilder);
|
|
if (useSiteDiagnosticsBuilder != null)
|
|
{
|
|
instance.AddRange(useSiteDiagnosticsBuilder);
|
|
}
|
|
Enumerator<TypeParameterDiagnosticInfo> enumerator = instance.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
TypeParameterDiagnosticInfo current = enumerator.Current;
|
|
int ordinal = current.TypeParameter.Ordinal;
|
|
Location val = ((ordinal < typeArgumentsSyntax.Count) ? ((SyntaxNode)typeArgumentsSyntax[ordinal]).Location : args.Location);
|
|
((BindingDiagnosticBag<AssemblySymbol>)(object)args.Diagnostics).Add(current.UseSiteInfo, val);
|
|
}
|
|
instance.Free();
|
|
if (HasDuplicateInterfaces(type, basesBeingResolved))
|
|
{
|
|
result = false;
|
|
args.Diagnostics.Add(ErrorCode.ERR_BogusType, args.Location, type);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static bool CheckConstraints(this NamedTypeSymbol type, in CheckConstraintsArgs args)
|
|
{
|
|
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!RequiresChecking(type))
|
|
{
|
|
return true;
|
|
}
|
|
ArrayBuilder<TypeParameterDiagnosticInfo> instance = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
|
|
ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
|
|
bool result = CheckTypeConstraints(type, in args, instance, args.IncludeNullability ? instance : null, ref useSiteDiagnosticsBuilder);
|
|
if (useSiteDiagnosticsBuilder != null)
|
|
{
|
|
instance.AddRange(useSiteDiagnosticsBuilder);
|
|
}
|
|
Enumerator<TypeParameterDiagnosticInfo> enumerator = instance.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
TypeParameterDiagnosticInfo current = enumerator.Current;
|
|
((BindingDiagnosticBag<AssemblySymbol>)(object)args.Diagnostics).Add(current.UseSiteInfo, args.Location);
|
|
}
|
|
instance.Free();
|
|
if ((args.CurrentCompilation == null || !type.IsFromCompilation(args.CurrentCompilation)) && HasDuplicateInterfaces(type, null))
|
|
{
|
|
result = false;
|
|
args.Diagnostics.Add(ErrorCode.ERR_BogusType, args.Location, type);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static bool HasDuplicateInterfaces(NamedTypeSymbol type, ConsList<TypeSymbol> basesBeingResolved)
|
|
{
|
|
ImmutableArray<NamedTypeSymbol> immutableArray = type.OriginalDefinition.InterfacesNoUseSiteDiagnostics(basesBeingResolved);
|
|
switch (immutableArray.Length)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
return false;
|
|
case 2:
|
|
if ((object)immutableArray[0].OriginalDefinition != immutableArray[1].OriginalDefinition)
|
|
{
|
|
return false;
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
PooledHashSet<object> instance = PooledHashSet<object>.GetInstance();
|
|
ImmutableArray<NamedTypeSymbol>.Enumerator enumerator = immutableArray.GetEnumerator();
|
|
NamedTypeSymbol current;
|
|
do
|
|
{
|
|
if (enumerator.MoveNext())
|
|
{
|
|
current = enumerator.Current;
|
|
continue;
|
|
}
|
|
instance.Free();
|
|
return false;
|
|
}
|
|
while (((HashSet<object>)(object)instance).Add((object)current.OriginalDefinition));
|
|
instance.Free();
|
|
break;
|
|
}
|
|
}
|
|
return ImmutableArrayExtensions.HasDuplicates<NamedTypeSymbol>(type.InterfacesNoUseSiteDiagnostics(basesBeingResolved), (IEqualityComparer<NamedTypeSymbol>)SymbolEqualityComparer.IgnoringDynamicTupleNamesAndNullability);
|
|
}
|
|
|
|
public static bool CheckConstraints(this MethodSymbol method, in CheckConstraintsArgs args)
|
|
{
|
|
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!RequiresChecking(method))
|
|
{
|
|
return true;
|
|
}
|
|
ArrayBuilder<TypeParameterDiagnosticInfo> instance = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
|
|
ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
|
|
bool result = CheckMethodConstraints(method, in args, instance, args.IncludeNullability ? instance : null, ref useSiteDiagnosticsBuilder);
|
|
if (useSiteDiagnosticsBuilder != null)
|
|
{
|
|
instance.AddRange(useSiteDiagnosticsBuilder);
|
|
}
|
|
Enumerator<TypeParameterDiagnosticInfo> enumerator = instance.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
TypeParameterDiagnosticInfo current = enumerator.Current;
|
|
((BindingDiagnosticBag<AssemblySymbol>)(object)args.Diagnostics).Add(current.UseSiteInfo, args.Location);
|
|
}
|
|
instance.Free();
|
|
return result;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
private static bool CheckTypeConstraints(NamedTypeSymbol type, in CheckConstraintsArgs args, ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder, ArrayBuilder<TypeParameterDiagnosticInfo> nullabilityDiagnosticsBuilderOpt, ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder)
|
|
{
|
|
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
|
|
return type.CheckConstraints(in args, type.TypeSubstitution, type.OriginalDefinition.TypeParameters, type.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics, diagnosticsBuilder, nullabilityDiagnosticsBuilderOpt, ref useSiteDiagnosticsBuilder);
|
|
}
|
|
|
|
public static bool CheckMethodConstraints(MethodSymbol method, in CheckConstraintsArgs args, ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder, ArrayBuilder<TypeParameterDiagnosticInfo> nullabilityDiagnosticsBuilderOpt, ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder, BitVector skipParameters = default(BitVector))
|
|
{
|
|
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
|
|
return method.CheckConstraints(in args, method.TypeSubstitution, method.OriginalDefinition.TypeParameters, method.TypeArgumentsWithAnnotations, diagnosticsBuilder, nullabilityDiagnosticsBuilderOpt, ref useSiteDiagnosticsBuilder, skipParameters);
|
|
}
|
|
|
|
public static bool CheckConstraints(this Symbol containingSymbol, in CheckConstraintsArgs args, TypeMap substitution, ImmutableArray<TypeParameterSymbol> typeParameters, ImmutableArray<TypeWithAnnotations> typeArguments, ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder, ArrayBuilder<TypeParameterDiagnosticInfo> nullabilityDiagnosticsBuilderOpt, ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder, BitVector skipParameters = default(BitVector), HashSet<TypeParameterSymbol> ignoreTypeConstraintsDependentOnTypeParametersOpt = null)
|
|
{
|
|
int length = typeParameters.Length;
|
|
bool result = true;
|
|
for (int i = 0; i < length; i++)
|
|
{
|
|
if (!((BitVector)(ref skipParameters))[i] && !CheckConstraints(containingSymbol, in args, substitution, typeParameters[i], typeArguments[i], diagnosticsBuilder, nullabilityDiagnosticsBuilderOpt, ref useSiteDiagnosticsBuilder, ignoreTypeConstraintsDependentOnTypeParametersOpt))
|
|
{
|
|
result = false;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
|
private static bool CheckBasicConstraints(Symbol containingSymbol, in CheckConstraintsArgs args, TypeParameterSymbol typeParameter, TypeWithAnnotations typeArgument, ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder, ArrayBuilder<TypeParameterDiagnosticInfo> nullabilityDiagnosticsBuilderOpt, ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder)
|
|
{
|
|
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0114: Invalid comparison between Unknown and I4
|
|
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_015f: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0161: Invalid comparison between Unknown and I4
|
|
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
|
|
if (typeArgument.Type.IsPointerOrFunctionPointer() || typeArgument.IsRestrictedType() || typeArgument.IsVoidType())
|
|
{
|
|
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_BadTypeArgument, typeArgument.Type))));
|
|
return false;
|
|
}
|
|
if (typeArgument.IsStatic)
|
|
{
|
|
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_GenericArgIsStaticClass, typeArgument.Type))));
|
|
return false;
|
|
}
|
|
if (typeParameter.HasReferenceTypeConstraint && !typeArgument.Type.IsReferenceType)
|
|
{
|
|
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_RefConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument.Type))));
|
|
return false;
|
|
}
|
|
CheckNullability(containingSymbol, typeParameter, typeArgument, nullabilityDiagnosticsBuilderOpt);
|
|
if (typeParameter.HasUnmanagedTypeConstraint)
|
|
{
|
|
CompoundUseSiteInfo<AssemblySymbol> useSiteInfo = default(CompoundUseSiteInfo<AssemblySymbol>);
|
|
useSiteInfo._002Ector(args.Template);
|
|
ManagedKind managedKind = typeArgument.Type.GetManagedKind(ref useSiteInfo);
|
|
AppendUseSiteDiagnostics(useSiteInfo, typeParameter, ref useSiteDiagnosticsBuilder);
|
|
if ((int)managedKind == 3 || !typeArgument.Type.IsNonNullableValueType())
|
|
{
|
|
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument.Type))));
|
|
return false;
|
|
}
|
|
if ((int)managedKind == 2 && args.CurrentCompilation != null)
|
|
{
|
|
CSDiagnosticInfo featureAvailabilityDiagnosticInfo = MessageID.IDS_FeatureUnmanagedConstructedTypes.GetFeatureAvailabilityDiagnosticInfo(args.CurrentCompilation);
|
|
if (featureAvailabilityDiagnosticInfo != null)
|
|
{
|
|
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)featureAvailabilityDiagnosticInfo)));
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
if (typeParameter.HasValueTypeConstraint && !typeArgument.Type.IsNonNullableValueType())
|
|
{
|
|
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_ValConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument.Type))));
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private static bool CheckConstraints(Symbol containingSymbol, in CheckConstraintsArgs args, TypeMap substitution, TypeParameterSymbol typeParameter, TypeWithAnnotations typeArgument, ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder, ArrayBuilder<TypeParameterDiagnosticInfo> nullabilityDiagnosticsBuilderOpt, ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder, HashSet<TypeParameterSymbol> ignoreTypeConstraintsDependentOnTypeParametersOpt)
|
|
{
|
|
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
|
|
if (typeArgument.Type.IsErrorType())
|
|
{
|
|
return true;
|
|
}
|
|
if (!CheckBasicConstraints(containingSymbol, in args, typeParameter, typeArgument, diagnosticsBuilder, nullabilityDiagnosticsBuilderOpt, ref useSiteDiagnosticsBuilder))
|
|
{
|
|
return false;
|
|
}
|
|
ArrayBuilder<TypeWithAnnotations> instance = ArrayBuilder<TypeWithAnnotations>.GetInstance();
|
|
CompoundUseSiteInfo<AssemblySymbol> useSiteInfo = default(CompoundUseSiteInfo<AssemblySymbol>);
|
|
useSiteInfo._002Ector(args.Template);
|
|
ImmutableArray<TypeWithAnnotations> original = typeParameter.ConstraintTypesWithDefinitionUseSiteDiagnostics(ref useSiteInfo);
|
|
substitution.SubstituteConstraintTypesDistinctWithoutModifiers(typeParameter, original, instance, ignoreTypeConstraintsDependentOnTypeParametersOpt);
|
|
bool hasError = false;
|
|
if (typeArgument.Type is NamedTypeSymbol { IsInterface: not false } namedTypeSymbol && SelfOrBaseHasStaticAbstractMember(namedTypeSymbol, ref useSiteInfo, out var memberWithoutImplementation))
|
|
{
|
|
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_GenericConstraintNotSatisfiedInterfaceWithStaticAbstractMembers, namedTypeSymbol, memberWithoutImplementation))));
|
|
hasError = true;
|
|
}
|
|
Enumerator<TypeWithAnnotations> enumerator = instance.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
TypeWithAnnotations current = enumerator.Current;
|
|
CheckConstraintType(containingSymbol, in args, typeParameter, typeArgument, diagnosticsBuilder, nullabilityDiagnosticsBuilderOpt, ref useSiteInfo, current, ref hasError);
|
|
}
|
|
instance.Free();
|
|
if (AppendUseSiteDiagnostics(useSiteInfo, typeParameter, ref useSiteDiagnosticsBuilder))
|
|
{
|
|
hasError = true;
|
|
}
|
|
if (typeParameter.HasConstructorConstraint && errorIfNotSatisfiesConstructorConstraint(containingSymbol, typeParameter, typeArgument, diagnosticsBuilder))
|
|
{
|
|
return false;
|
|
}
|
|
return !hasError;
|
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
|
static bool errorIfNotSatisfiesConstructorConstraint(Symbol symbol, TypeParameterSymbol typeParameterSymbol, TypeWithAnnotations typeWithAnnotations, ArrayBuilder<TypeParameterDiagnosticInfo> val)
|
|
{
|
|
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
|
|
ConstructorConstraintError constructorConstraintError = SatisfiesConstructorConstraint(typeWithAnnotations.Type);
|
|
switch (constructorConstraintError)
|
|
{
|
|
case ConstructorConstraintError.None:
|
|
return false;
|
|
case ConstructorConstraintError.NoPublicParameterlessConstructorOrAbstractType:
|
|
val.Add(new TypeParameterDiagnosticInfo(typeParameterSymbol, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_NewConstraintNotSatisfied, symbol.ConstructedFrom(), typeParameterSymbol, typeWithAnnotations.Type))));
|
|
return true;
|
|
case ConstructorConstraintError.HasRequiredMembers:
|
|
val.Add(new TypeParameterDiagnosticInfo(typeParameterSymbol, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_NewConstraintCannotHaveRequiredMembers, symbol.ConstructedFrom(), typeParameterSymbol, typeWithAnnotations.Type))));
|
|
return true;
|
|
default:
|
|
throw ExceptionUtilities.UnexpectedValue((object)constructorConstraintError);
|
|
}
|
|
}
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
|
private static void CheckNullability(Symbol containingSymbol, TypeParameterSymbol typeParameter, TypeWithAnnotations typeArgument, ArrayBuilder<TypeParameterDiagnosticInfo> nullabilityDiagnosticsBuilderOpt)
|
|
{
|
|
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
|
|
if (nullabilityDiagnosticsBuilderOpt != null)
|
|
{
|
|
if (typeParameter.HasNotNullConstraint && typeArgument.GetValueNullableAnnotation().IsAnnotated() && !typeArgument.Type.IsNonNullableValueType())
|
|
{
|
|
nullabilityDiagnosticsBuilderOpt.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.WRN_NullabilityMismatchInTypeParameterNotNullConstraint, containingSymbol.ConstructedFrom(), typeParameter, typeArgument))));
|
|
}
|
|
if (typeParameter.HasReferenceTypeConstraint && typeParameter.ReferenceTypeConstraintIsNullable == false && typeArgument.GetValueNullableAnnotation().IsAnnotated())
|
|
{
|
|
nullabilityDiagnosticsBuilderOpt.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.WRN_NullabilityMismatchInTypeParameterReferenceTypeConstraint, containingSymbol.ConstructedFrom(), typeParameter, typeArgument))));
|
|
}
|
|
}
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
|
private static void CheckConstraintType(Symbol containingSymbol, in CheckConstraintsArgs args, TypeParameterSymbol typeParameter, TypeWithAnnotations typeArgument, ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder, ArrayBuilder<TypeParameterDiagnosticInfo> nullabilityDiagnosticsBuilderOpt, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo, TypeWithAnnotations constraintType, ref bool hasError)
|
|
{
|
|
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00cc: Invalid comparison between Unknown and I4
|
|
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
|
|
if (SatisfiesConstraintType(args.Conversions.WithNullability(includeNullability: false), typeArgument, constraintType, ref useSiteInfo))
|
|
{
|
|
if (nullabilityDiagnosticsBuilderOpt != null && (!SatisfiesConstraintType(args.Conversions.WithNullability(includeNullability: true), typeArgument, constraintType, ref useSiteInfo) || !constraintTypeAllows(in constraintType, getTypeArgumentState(in typeArgument))))
|
|
{
|
|
nullabilityDiagnosticsBuilderOpt.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, containingSymbol.ConstructedFrom(), constraintType, typeParameter, typeArgument))));
|
|
}
|
|
return;
|
|
}
|
|
ErrorCode code = (typeArgument.Type.IsReferenceType ? ErrorCode.ERR_GenericConstraintNotSatisfiedRefType : (typeArgument.IsNullableType() ? (constraintType.Type.IsInterfaceType() ? ErrorCode.ERR_GenericConstraintNotSatisfiedNullableInterface : ErrorCode.ERR_GenericConstraintNotSatisfiedNullableEnum) : (((int)typeArgument.TypeKind != 11) ? ErrorCode.ERR_GenericConstraintNotSatisfiedValType : ErrorCode.ERR_GenericConstraintNotSatisfiedTyVar)));
|
|
object obj;
|
|
object obj2;
|
|
if (constraintType.Type.Equals(typeArgument.Type, (TypeCompareKind)63))
|
|
{
|
|
obj = constraintType.Type;
|
|
obj2 = typeArgument.Type;
|
|
}
|
|
else
|
|
{
|
|
SymbolDistinguisher symbolDistinguisher = new SymbolDistinguisher(args.CurrentCompilation, constraintType.Type, typeArgument.Type);
|
|
obj = symbolDistinguisher.First;
|
|
obj2 = symbolDistinguisher.Second;
|
|
}
|
|
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(code, containingSymbol.ConstructedFrom(), obj, typeParameter, obj2))));
|
|
hasError = true;
|
|
static bool constraintTypeAllows(in TypeWithAnnotations typeWithAnnotations, NullableFlowState state)
|
|
{
|
|
if (state == NullableFlowState.NotNull)
|
|
{
|
|
return true;
|
|
}
|
|
TypeSymbol type = typeWithAnnotations.Type;
|
|
if ((object)type == null || type.IsValueType)
|
|
{
|
|
return true;
|
|
}
|
|
NullableAnnotation nullableAnnotation = typeWithAnnotations.NullableAnnotation;
|
|
if (nullableAnnotation - 1 <= NullableAnnotation.Oblivious)
|
|
{
|
|
return true;
|
|
}
|
|
if (!(type is TypeParameterSymbol { IsNotNullable: var isNotNullable } typeParameterSymbol) || isNotNullable == true)
|
|
{
|
|
return false;
|
|
}
|
|
ImmutableArray<TypeWithAnnotations>.Enumerator enumerator = typeParameterSymbol.ConstraintTypesNoUseSiteDiagnostics.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
if (!constraintTypeAllows(enumerator.Current, state))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return state == NullableFlowState.MaybeNull;
|
|
}
|
|
static NullableFlowState getTypeArgumentState(in TypeWithAnnotations typeWithAnnotations)
|
|
{
|
|
TypeSymbol type = typeWithAnnotations.Type;
|
|
if ((object)type == null)
|
|
{
|
|
return NullableFlowState.NotNull;
|
|
}
|
|
if (type.IsValueType)
|
|
{
|
|
if (!type.IsNullableTypeOrTypeParameter())
|
|
{
|
|
return NullableFlowState.NotNull;
|
|
}
|
|
return NullableFlowState.MaybeNull;
|
|
}
|
|
switch (typeWithAnnotations.NullableAnnotation)
|
|
{
|
|
case NullableAnnotation.Annotated:
|
|
if (!type.IsTypeParameterDisallowingAnnotationInCSharp8())
|
|
{
|
|
return NullableFlowState.MaybeNull;
|
|
}
|
|
return NullableFlowState.MaybeDefault;
|
|
case NullableAnnotation.Oblivious:
|
|
return NullableFlowState.NotNull;
|
|
default:
|
|
{
|
|
if (!(type is TypeParameterSymbol { IsNotNullable: var isNotNullable } typeParameterSymbol) || isNotNullable == true)
|
|
{
|
|
return NullableFlowState.NotNull;
|
|
}
|
|
NullableFlowState? nullableFlowState = null;
|
|
ImmutableArray<TypeWithAnnotations>.Enumerator enumerator = typeParameterSymbol.ConstraintTypesNoUseSiteDiagnostics.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
NullableFlowState nullableFlowState2 = getTypeArgumentState(enumerator.Current);
|
|
nullableFlowState = (nullableFlowState.HasValue ? new NullableFlowState?(nullableFlowState.Value.Meet(nullableFlowState2)) : new NullableFlowState?(nullableFlowState2));
|
|
}
|
|
return nullableFlowState ?? NullableFlowState.MaybeNull;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static bool AppendUseSiteDiagnostics(CompoundUseSiteInfo<AssemblySymbol> useSiteInfo, TypeParameterSymbol typeParameter, ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder)
|
|
{
|
|
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00aa: Invalid comparison between Unknown and I4
|
|
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
|
|
if ((!useSiteInfo.AccumulatesDiagnostics || !useSiteInfo.HasErrors) && useSiteInfo.AccumulatesDependencies && !CollectionsExtensions.IsNullOrEmpty<AssemblySymbol>(useSiteInfo.Dependencies))
|
|
{
|
|
ensureUseSiteDiagnosticsBuilder(ref useSiteDiagnosticsBuilder).Add(new TypeParameterDiagnosticInfo(typeParameter, (useSiteInfo.Dependencies.Count == 1) ? new UseSiteInfo<AssemblySymbol>(useSiteInfo.Dependencies.Single()) : new UseSiteInfo<AssemblySymbol>(useSiteInfo.Dependencies.ToImmutableHashSet())));
|
|
}
|
|
if (!useSiteInfo.AccumulatesDiagnostics)
|
|
{
|
|
return false;
|
|
}
|
|
IReadOnlyCollection<DiagnosticInfo> diagnostics = useSiteInfo.Diagnostics;
|
|
if (CollectionsExtensions.IsNullOrEmpty<DiagnosticInfo>(diagnostics))
|
|
{
|
|
return false;
|
|
}
|
|
ensureUseSiteDiagnosticsBuilder(ref useSiteDiagnosticsBuilder);
|
|
bool result = false;
|
|
foreach (DiagnosticInfo item in diagnostics)
|
|
{
|
|
if ((int)item.Severity == 3)
|
|
{
|
|
result = true;
|
|
}
|
|
useSiteDiagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>(item)));
|
|
}
|
|
return result;
|
|
static ArrayBuilder<TypeParameterDiagnosticInfo> ensureUseSiteDiagnosticsBuilder(ref ArrayBuilder<TypeParameterDiagnosticInfo> reference)
|
|
{
|
|
return reference ?? (reference = new ArrayBuilder<TypeParameterDiagnosticInfo>());
|
|
}
|
|
}
|
|
|
|
private static bool SatisfiesConstraintType(ConversionsBase conversions, TypeWithAnnotations typeArgument, TypeWithAnnotations constraintType, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
|
|
{
|
|
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_007a: Invalid comparison between Unknown and I4
|
|
if (constraintType.Type.IsErrorType())
|
|
{
|
|
return false;
|
|
}
|
|
if (conversions.HasIdentityOrImplicitReferenceConversion(typeArgument.Type, constraintType.Type, ref useSiteInfo))
|
|
{
|
|
return true;
|
|
}
|
|
if (typeArgument.Type.IsValueType && conversions.HasBoxingConversion(typeArgument.Type.IsNullableType() ? ((NamedTypeSymbol)typeArgument.Type).ConstructedFrom : typeArgument.Type, constraintType.Type, ref useSiteInfo))
|
|
{
|
|
return true;
|
|
}
|
|
if ((int)typeArgument.TypeKind == 11)
|
|
{
|
|
TypeParameterSymbol typeParameterSymbol = (TypeParameterSymbol)typeArgument.Type;
|
|
if (conversions.HasImplicitTypeParameterConversion(typeParameterSymbol, constraintType.Type, ref useSiteInfo))
|
|
{
|
|
return true;
|
|
}
|
|
ImmutableArray<TypeWithAnnotations>.Enumerator enumerator = typeParameterSymbol.ConstraintTypesWithDefinitionUseSiteDiagnostics(ref useSiteInfo).GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
TypeWithAnnotations current = enumerator.Current;
|
|
if (SatisfiesConstraintType(conversions, current, constraintType, ref useSiteInfo))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static bool SelfOrBaseHasStaticAbstractMember(NamedTypeSymbol iface, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo, out Symbol memberWithoutImplementation)
|
|
{
|
|
ImmutableArray<Symbol>.Enumerator enumerator = iface.GetMembers().GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Symbol current = enumerator.Current;
|
|
if (current.IsStatic && current.IsImplementableInterfaceMember() && (object)iface.FindImplementationForInterfaceMember(current) == null)
|
|
{
|
|
memberWithoutImplementation = current;
|
|
return true;
|
|
}
|
|
}
|
|
foreach (NamedTypeSymbol key in iface.InterfacesAndTheirBaseInterfacesNoUseSiteDiagnostics.Keys)
|
|
{
|
|
enumerator = key.GetMembers().GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Symbol current3 = enumerator.Current;
|
|
if (current3.IsStatic && current3.IsImplementableInterfaceMember() && (object)iface.FindImplementationForInterfaceMember(current3) == null)
|
|
{
|
|
memberWithoutImplementation = current3;
|
|
return true;
|
|
}
|
|
}
|
|
key.OriginalDefinition.AddUseSiteInfo(ref useSiteInfo);
|
|
}
|
|
memberWithoutImplementation = null;
|
|
return false;
|
|
}
|
|
|
|
private static bool IsReferenceType(TypeParameterSymbol typeParameter, ImmutableArray<TypeWithAnnotations> constraintTypes)
|
|
{
|
|
if (!typeParameter.HasReferenceTypeConstraint)
|
|
{
|
|
return TypeParameterSymbol.CalculateIsReferenceTypeFromConstraintTypes(constraintTypes);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private static bool IsValueType(TypeParameterSymbol typeParameter, ImmutableArray<TypeWithAnnotations> constraintTypes)
|
|
{
|
|
if (!typeParameter.HasValueTypeConstraint)
|
|
{
|
|
return TypeParameterSymbol.CalculateIsValueTypeFromConstraintTypes(constraintTypes);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private static TypeParameterDiagnosticInfo GenerateConflictingConstraintsError(TypeParameterSymbol typeParameter, TypeSymbol deducedBase, bool classConflict)
|
|
{
|
|
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
|
|
return new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo<AssemblySymbol>((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_BaseConstraintConflict, typeParameter, deducedBase, classConflict ? "class" : "struct")));
|
|
}
|
|
|
|
private static void AddInterfaces(ArrayBuilder<NamedTypeSymbol> builder, ImmutableArray<NamedTypeSymbol> interfaces)
|
|
{
|
|
ImmutableArray<NamedTypeSymbol>.Enumerator enumerator = interfaces.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
NamedTypeSymbol current = enumerator.Current;
|
|
AddInterface(builder, current);
|
|
}
|
|
}
|
|
|
|
private static void AddInterface(ArrayBuilder<NamedTypeSymbol> builder, NamedTypeSymbol @interface)
|
|
{
|
|
if (!builder.Contains(@interface))
|
|
{
|
|
builder.Add(@interface);
|
|
}
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
|
private static ConstructorConstraintError SatisfiesConstructorConstraint(TypeSymbol typeArgument)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_003b: Expected I4, but got Unknown
|
|
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
|
|
TypeKind typeKind = typeArgument.TypeKind;
|
|
switch (typeKind - 2)
|
|
{
|
|
case 8:
|
|
return SatisfiesPublicParameterlessConstructor((NamedTypeSymbol)typeArgument, synthesizedIfMissing: true);
|
|
case 2:
|
|
case 3:
|
|
return ConstructorConstraintError.None;
|
|
case 0:
|
|
if (typeArgument.IsAbstract)
|
|
{
|
|
return ConstructorConstraintError.NoPublicParameterlessConstructorOrAbstractType;
|
|
}
|
|
return SatisfiesPublicParameterlessConstructor((NamedTypeSymbol)typeArgument, synthesizedIfMissing: false);
|
|
case 9:
|
|
{
|
|
TypeParameterSymbol typeParameterSymbol = (TypeParameterSymbol)typeArgument;
|
|
if (!typeParameterSymbol.HasConstructorConstraint && !typeParameterSymbol.IsValueType)
|
|
{
|
|
return ConstructorConstraintError.NoPublicParameterlessConstructorOrAbstractType;
|
|
}
|
|
return ConstructorConstraintError.None;
|
|
}
|
|
case 10:
|
|
throw ExceptionUtilities.UnexpectedValue((object)typeArgument.TypeKind);
|
|
default:
|
|
return ConstructorConstraintError.NoPublicParameterlessConstructorOrAbstractType;
|
|
}
|
|
}
|
|
|
|
private static ConstructorConstraintError SatisfiesPublicParameterlessConstructor(NamedTypeSymbol type, bool synthesizedIfMissing)
|
|
{
|
|
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002f: Invalid comparison between Unknown and I4
|
|
bool hasAnyRequiredMembers = type.HasAnyRequiredMembers;
|
|
ImmutableArray<MethodSymbol>.Enumerator enumerator = type.InstanceConstructors.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
MethodSymbol current = enumerator.Current;
|
|
if (current.ParameterCount == 0)
|
|
{
|
|
if ((int)current.DeclaredAccessibility != 6)
|
|
{
|
|
return ConstructorConstraintError.NoPublicParameterlessConstructorOrAbstractType;
|
|
}
|
|
if (hasAnyRequiredMembers && current.ShouldCheckRequiredMembers())
|
|
{
|
|
return ConstructorConstraintError.HasRequiredMembers;
|
|
}
|
|
return ConstructorConstraintError.None;
|
|
}
|
|
}
|
|
if (synthesizedIfMissing)
|
|
{
|
|
if (hasAnyRequiredMembers)
|
|
{
|
|
return ConstructorConstraintError.HasRequiredMembers;
|
|
}
|
|
return ConstructorConstraintError.None;
|
|
}
|
|
return ConstructorConstraintError.NoPublicParameterlessConstructorOrAbstractType;
|
|
}
|
|
|
|
private static bool IsEncompassedBy(ConversionsBase conversions, TypeSymbol a, TypeSymbol b, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
|
|
{
|
|
if (!conversions.HasIdentityOrImplicitReferenceConversion(a, b, ref useSiteInfo))
|
|
{
|
|
return conversions.HasBoxingConversion(a, b, ref useSiteInfo);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private static bool IsValidEncompassedByArgument(TypeSymbol type)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000b: Invalid comparison between Unknown and I4
|
|
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000f: Invalid comparison between Unknown and I4
|
|
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0014: Invalid comparison between Unknown and I4
|
|
TypeKind typeKind = type.TypeKind;
|
|
if (typeKind - 1 <= 2 || (int)typeKind == 5 || (int)typeKind == 10)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static bool RequiresChecking(NamedTypeSymbol type)
|
|
{
|
|
if (type.Arity == 0)
|
|
{
|
|
return false;
|
|
}
|
|
if ((object)type.OriginalDefinition == type)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static bool RequiresChecking(MethodSymbol method)
|
|
{
|
|
if (!method.IsGenericMethod)
|
|
{
|
|
return false;
|
|
}
|
|
if ((object)method.OriginalDefinition == method)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
[Conditional("DEBUG")]
|
|
private static void CheckEffectiveAndDeducedBaseTypes(ConversionsBase conversions, TypeSymbol effectiveBase, TypeSymbol deducedBase)
|
|
{
|
|
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
|
|
_ = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
|
|
}
|
|
|
|
internal static TypeWithAnnotations ConstraintWithMostSignificantNullability(TypeWithAnnotations type1, TypeWithAnnotations type2)
|
|
{
|
|
switch (type2.NullableAnnotation)
|
|
{
|
|
case NullableAnnotation.Annotated:
|
|
return type1;
|
|
case NullableAnnotation.NotAnnotated:
|
|
return type2;
|
|
case NullableAnnotation.Oblivious:
|
|
if (type1.NullableAnnotation.IsNotAnnotated())
|
|
{
|
|
return type1;
|
|
}
|
|
return type2;
|
|
default:
|
|
throw ExceptionUtilities.UnexpectedValue((object)type2.NullableAnnotation);
|
|
}
|
|
}
|
|
|
|
internal static bool IsObjectConstraint(TypeWithAnnotations type, ref TypeWithAnnotations bestObjectConstraint)
|
|
{
|
|
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0008: Invalid comparison between Unknown and I4
|
|
if ((int)type.SpecialType == 1)
|
|
{
|
|
if (type.NullableAnnotation != NullableAnnotation.Annotated)
|
|
{
|
|
if (!bestObjectConstraint.HasType)
|
|
{
|
|
bestObjectConstraint = type;
|
|
}
|
|
else
|
|
{
|
|
bestObjectConstraint = ConstraintWithMostSignificantNullability(bestObjectConstraint, type);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
internal static bool IsObjectConstraintSignificant(bool? isNotNullable, TypeWithAnnotations objectConstraint)
|
|
{
|
|
if (isNotNullable.HasValue)
|
|
{
|
|
if (isNotNullable == true)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if (objectConstraint.NullableAnnotation.IsOblivious())
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|