Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a concept of internal special types, move all members defined in special types to the SpecialMember set. #72646

Merged
merged 4 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1654,9 +1654,14 @@ internal static NamedTypeSymbol GetSpecialType(CSharpCompilation compilation, Sp
/// member isn't found.
/// </summary>
internal Symbol GetSpecialTypeMember(SpecialMember member, BindingDiagnosticBag diagnostics, SyntaxNode syntax)
{
return GetSpecialTypeMember(this.Compilation, member, diagnostics, syntax);
}

internal static Symbol GetSpecialTypeMember(CSharpCompilation compilation, SpecialMember member, BindingDiagnosticBag diagnostics, SyntaxNode syntax)
{
Symbol memberSymbol;
return TryGetSpecialTypeMember(this.Compilation, member, syntax, diagnostics, out memberSymbol)
return TryGetSpecialTypeMember(compilation, member, syntax, diagnostics, out memberSymbol)
? memberSymbol
: null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1629,9 +1629,9 @@ internal AliasSymbol GlobalNamespaceAlias
/// <summary>
/// Get the symbol for the predefined type from the COR Library referenced by this compilation.
/// </summary>
internal new NamedTypeSymbol GetSpecialType(SpecialType specialType)
internal NamedTypeSymbol GetSpecialType(ExtendedSpecialType specialType)
{
if (specialType <= SpecialType.None || specialType > SpecialType.Count)
if ((int)specialType <= (int)SpecialType.None || (int)specialType >= (int)InternalSpecialType.NextAvailable)
{
throw new ArgumentOutOfRangeException(nameof(specialType), $"Unexpected SpecialType: '{(int)specialType}'.");
}
Expand All @@ -1647,7 +1647,7 @@ internal AliasSymbol GlobalNamespaceAlias
result = Assembly.GetSpecialType(specialType);
}

Debug.Assert(result.SpecialType == specialType);
Debug.Assert(result.ExtendedSpecialType == specialType);
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,9 @@ static bool hasOverriddenToString(TypeSymbol variableType)
private MethodSymbol? GetWellKnownMethodSymbol(WellKnownMember overload, SyntaxNode syntax)
=> (MethodSymbol?)Binder.GetWellKnownTypeMember(_factory.Compilation, overload, _diagnostics, syntax: syntax, isOptional: false);

private MethodSymbol? GetSpecialMethodSymbol(SpecialMember overload, SyntaxNode syntax)
=> (MethodSymbol?)Binder.GetSpecialTypeMember(_factory.Compilation, overload, _diagnostics, syntax: syntax);

public override void PreInstrumentBlock(BoundBlock original, LocalRewriter rewriter)
{
Previous.PreInstrumentBlock(original, rewriter);
Expand Down Expand Up @@ -456,7 +459,7 @@ private ImmutableArray<BoundExpression> MakeStoreLoggerArguments(

if (parameter.Type.SpecialType == SpecialType.System_String && targetType.SpecialType != SpecialType.System_String)
{
var toStringMethod = GetWellKnownMethodSymbol(WellKnownMember.System_Object__ToString, value.Syntax);
var toStringMethod = GetSpecialMethodSymbol(SpecialMember.System_Object__ToString, value.Syntax);

BoundExpression toString;
if (toStringMethod is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ private static MethodSymbol UnsafeGetSpecialTypeMethod(SyntaxNode syntax, Specia
else
{
MemberDescriptor descriptor = SpecialMembers.GetDescriptor(specialMember);
SpecialType type = (SpecialType)descriptor.DeclaringTypeId;
ExtendedSpecialType type = descriptor.DeclaringSpecialType;
TypeSymbol container = compilation.Assembly.GetSpecialType(type);
TypeSymbol returnType = new ExtendedErrorTypeSymbol(compilation: compilation, name: descriptor.Name, errorInfo: null, arity: descriptor.Arity);
return new ErrorMethodSymbol(container, returnType, "Missing");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1404,7 +1404,7 @@ private BoundExpression CreateEmptyArray(SyntaxNode syntax, ArrayTypeSymbol arra
return null;
}

MethodSymbol? arrayEmpty = _compilation.GetWellKnownTypeMember(WellKnownMember.System_Array__Empty) as MethodSymbol;
MethodSymbol? arrayEmpty = _compilation.GetSpecialTypeMember(SpecialMember.System_Array__Empty) as MethodSymbol;
if (arrayEmpty is null) // will be null if Array.Empty<T> doesn't exist in reference assemblies
{
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ private BoundStatement InitializeFixedStatementArrayLocal(
else
{
MethodSymbol? lengthMethod;
if (TryGetWellKnownTypeMember(fixedInitializer.Syntax, WellKnownMember.System_Array__get_Length, out lengthMethod))
if (TryGetSpecialTypeMethod(fixedInitializer.Syntax, SpecialMember.System_Array__get_Length, out lengthMethod))
{
lengthCall = factory.Call(factory.Local(pinnedTemp), lengthMethod);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,22 +397,56 @@ public MethodSymbol WellKnownMethod(WellKnownMember wm)
/// <param name="sm">The desired special member</param>
/// <returns>A symbol for the special member.</returns>
public Symbol SpecialMember(SpecialMember sm)
{
var result = SpecialMember(sm, isOptional: false);
Debug.Assert(result is not null);
return result;
}

public Symbol? SpecialMember(SpecialMember sm, bool isOptional = false)
{
Symbol specialMember = Compilation.GetSpecialTypeMember(sm);
if (specialMember is null)
{
if (isOptional)
{
return null;
}

RuntimeMembers.MemberDescriptor memberDescriptor = SpecialMembers.GetDescriptor(sm);
var diagnostic = new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_MissingPredefinedMember, memberDescriptor.DeclaringTypeMetadataName, memberDescriptor.Name), Syntax.Location);
throw new MissingPredefinedMember(diagnostic);
}

Binder.ReportUseSite(specialMember, Diagnostics, Syntax);
UseSiteInfo<AssemblySymbol> useSiteInfo = specialMember.GetUseSiteInfo();

if (isOptional)
{
if (useSiteInfo.DiagnosticInfo?.DefaultSeverity == DiagnosticSeverity.Error)
{
return null;
}

// Not interested in warnings
}
else
{
Diagnostics.Add(useSiteInfo, Syntax);
}

return specialMember;
}

public MethodSymbol SpecialMethod(SpecialMember sm)
{
return (MethodSymbol)SpecialMember(sm);
var result = (MethodSymbol?)SpecialMember(sm, isOptional: false);
Debug.Assert(result is not null);
return result;
}

public MethodSymbol? SpecialMethod(SpecialMember sm, bool isOptional)
{
return (MethodSymbol?)SpecialMember(sm, isOptional);
}

public PropertySymbol SpecialProperty(SpecialMember sm)
Expand Down Expand Up @@ -1287,12 +1321,18 @@ public BoundExpression Sizeof(TypeSymbol type)

internal BoundExpression ConstructorInfo(MethodSymbol ctor)
{
return new BoundMethodInfo(
var result = new BoundMethodInfo(
Syntax,
ctor,
GetMethodFromHandleMethod(ctor.ContainingType),
WellKnownType(Microsoft.CodeAnalysis.WellKnownType.System_Reflection_ConstructorInfo))
{ WasCompilerGenerated = true };

#if DEBUG
var discardedUseSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
Debug.Assert(result.Type.IsErrorType() || result.Type!.IsDerivedFrom(result.GetMethodFromHandle!.ReturnType, TypeCompareKind.AllIgnoreOptions, ref discardedUseSiteInfo));
#endif
return result;
}

public BoundExpression MethodDefIndex(MethodSymbol method)
Expand Down Expand Up @@ -1388,12 +1428,18 @@ public BoundExpression MethodInfo(MethodSymbol method)
method = method.GetConstructedLeastOverriddenMethod(this.CompilationState.Type, requireSameReturnType: true);
}

return new BoundMethodInfo(
var result = new BoundMethodInfo(
Syntax,
method,
GetMethodFromHandleMethod(method.ContainingType),
WellKnownType(Microsoft.CodeAnalysis.WellKnownType.System_Reflection_MethodInfo))
{ WasCompilerGenerated = true };

#if DEBUG
var discardedUseSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
Debug.Assert(result.Type.IsErrorType() || result.Type!.IsDerivedFrom(result.GetMethodFromHandle!.ReturnType, TypeCompareKind.AllIgnoreOptions, ref discardedUseSiteInfo));
#endif
return result;
}

public BoundExpression FieldInfo(FieldSymbol field)
Expand Down Expand Up @@ -1486,7 +1532,7 @@ public BoundExpression ArrayOrEmpty(TypeSymbol elementType, ImmutableArray<Bound
{
if (elements.Length == 0)
{
MethodSymbol? arrayEmpty = WellKnownMethod(CodeAnalysis.WellKnownMember.System_Array__Empty, isOptional: true);
MethodSymbol? arrayEmpty = SpecialMethod(CodeAnalysis.SpecialMember.System_Array__Empty, isOptional: true);
if (arrayEmpty is { })
{
arrayEmpty = arrayEmpty.Construct(ImmutableArray.Create(elementType));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public bool ReportMissingOrErroneousSymbols(BindingDiagnosticBag diagnostics)
ReportErrorOnSpecialMember(System_Object__Equals, SpecialMember.System_Object__Equals, diagnostics, ref hasErrors);
ReportErrorOnSpecialMember(System_Object__ToString, SpecialMember.System_Object__ToString, diagnostics, ref hasErrors);
ReportErrorOnSpecialMember(System_Object__GetHashCode, SpecialMember.System_Object__GetHashCode, diagnostics, ref hasErrors);
ReportErrorOnWellKnownMember(System_String__Format_IFormatProvider, WellKnownMember.System_String__Format_IFormatProvider, diagnostics, ref hasErrors);
ReportErrorOnSpecialMember(System_String__Format_IFormatProvider, SpecialMember.System_String__Format_IFormatProvider, diagnostics, ref hasErrors);

// optional synthesized attributes:
Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor));
Expand Down Expand Up @@ -178,7 +178,7 @@ public MethodSymbol System_Collections_Generic_EqualityComparer_T__get_Default

public MethodSymbol System_String__Format_IFormatProvider
{
get { return this.Compilation.GetWellKnownTypeMember(WellKnownMember.System_String__Format_IFormatProvider) as MethodSymbol; }
get { return this.Compilation.GetSpecialTypeMember(SpecialMember.System_String__Format_IFormatProvider) as MethodSymbol; }
}

#endregion
Expand Down
6 changes: 3 additions & 3 deletions src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ internal ErrorTypeSymbol CreateMultipleForwardingErrorTypeSymbol(ref MetadataTyp
/// Lookup declaration for predefined CorLib type in this Assembly.
/// </summary>
/// <returns>The symbol for the pre-defined type or an error type if the type is not defined in the core library.</returns>
internal abstract NamedTypeSymbol GetDeclaredSpecialType(SpecialType type);
internal abstract NamedTypeSymbol GetDeclaredSpecialType(ExtendedSpecialType type);

/// <summary>
/// Register declaration of predefined CorLib type in this Assembly.
Expand Down Expand Up @@ -480,7 +480,7 @@ internal bool RuntimeSupportsInlineArrayTypes
protected bool RuntimeSupportsFeature(SpecialMember feature)
{
// Keep in sync with VB's AssemblySymbol.RuntimeSupportsFeature
Debug.Assert((SpecialType)SpecialMembers.GetDescriptor(feature).DeclaringTypeId == SpecialType.System_Runtime_CompilerServices_RuntimeFeature);
Debug.Assert(SpecialMembers.GetDescriptor(feature).DeclaringSpecialType == SpecialType.System_Runtime_CompilerServices_RuntimeFeature);
return GetSpecialType(SpecialType.System_Runtime_CompilerServices_RuntimeFeature) is { TypeKind: TypeKind.Class, IsStatic: true } &&
GetSpecialTypeMember(feature) is object;
}
Expand Down Expand Up @@ -584,7 +584,7 @@ bool IAssemblySymbolInternal.AreInternalsVisibleToThisAssembly(IAssemblySymbolIn
/// Gets the symbol for the pre-defined type from core library associated with this assembly.
/// </summary>
/// <returns>The symbol for the pre-defined type or an error type if the type is not defined in the core library.</returns>
internal NamedTypeSymbol GetSpecialType(SpecialType type)
internal NamedTypeSymbol GetSpecialType(ExtendedSpecialType type)
{
return CorLibrary.GetDeclaredSpecialType(type);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ private void SetUsesNullableAttributes()
}

MemberDescriptor descriptor = WellKnownMembers.GetDescriptor(member);
NamedTypeSymbol type = descriptor.DeclaringTypeId <= (int)SpecialType.Count
? this.GetSpecialType((SpecialType)descriptor.DeclaringTypeId)
: this.GetWellKnownType((WellKnownType)descriptor.DeclaringTypeId);
NamedTypeSymbol type = descriptor.IsSpecialTypeMember
? this.GetSpecialType(descriptor.DeclaringSpecialType)
: this.GetWellKnownType(descriptor.DeclaringWellKnownType);
Symbol? result = null;

if (!type.IsErrorType())
Expand Down Expand Up @@ -1223,7 +1223,7 @@ protected override bool MatchArrayRank(TypeSymbol type, int countOfDimensions)

protected override bool MatchTypeToTypeId(TypeSymbol type, int typeId)
{
if ((int)type.OriginalDefinition.SpecialType == typeId)
if ((int)type.OriginalDefinition.ExtendedSpecialType == typeId)
{
if (type.IsDefinition)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ internal abstract class PENamedTypeSymbol : NamedTypeSymbol
private readonly TypeDefinitionHandle _handle;
private readonly string _name;
private readonly TypeAttributes _flags;
private readonly SpecialType _corTypeId;
private readonly ExtendedSpecialType _corTypeId;

/// <summary>
/// A set of all the names of the members in this type.
Expand Down Expand Up @@ -356,7 +356,7 @@ private PENamedTypeSymbol(
}
}

public override SpecialType SpecialType
public override ExtendedSpecialType ExtendedSpecialType
{
get
{
Expand Down Expand Up @@ -2136,7 +2136,7 @@ protected virtual DiagnosticInfo GetUseSiteDiagnosticImpl()
if ((object)missingType != null && missingType.Arity == 0)
{
string emittedName = MetadataHelpers.BuildQualifiedName(missingType.NamespaceName, missingType.MetadataName);
switch (SpecialTypes.GetTypeFromMetadataName(emittedName))
switch ((SpecialType)SpecialTypes.GetTypeFromMetadataName(emittedName))
{
case SpecialType.System_Enum:
case SpecialType.System_MulticastDelegate:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ internal abstract class MetadataOrSourceAssemblySymbol
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
internal sealed override NamedTypeSymbol GetDeclaredSpecialType(SpecialType type)
internal sealed override NamedTypeSymbol GetDeclaredSpecialType(ExtendedSpecialType type)
{
#if DEBUG
foreach (var module in this.Modules)
Expand Down Expand Up @@ -79,7 +79,7 @@ internal sealed override NamedTypeSymbol GetDeclaredSpecialType(SpecialType type
/// <param name="corType"></param>
internal sealed override void RegisterDeclaredSpecialType(NamedTypeSymbol corType)
{
SpecialType typeId = corType.SpecialType;
ExtendedSpecialType typeId = corType.ExtendedSpecialType;
Debug.Assert(typeId != SpecialType.None);
Debug.Assert(ReferenceEquals(corType.ContainingAssembly, this));
Debug.Assert(corType.ContainingModule.Ordinal == 0);
Expand All @@ -88,7 +88,7 @@ internal sealed override void RegisterDeclaredSpecialType(NamedTypeSymbol corTyp
if (_lazySpecialTypes == null)
{
Interlocked.CompareExchange(ref _lazySpecialTypes,
new NamedTypeSymbol[(int)SpecialType.Count + 1], null);
new NamedTypeSymbol[(int)InternalSpecialType.NextAvailable], null);
}

if ((object)Interlocked.CompareExchange(ref _lazySpecialTypes[(int)typeId], corType, null) != null)
Expand All @@ -100,7 +100,7 @@ internal sealed override void RegisterDeclaredSpecialType(NamedTypeSymbol corTyp
else
{
Interlocked.Increment(ref _cachedSpecialTypes);
Debug.Assert(_cachedSpecialTypes > 0 && _cachedSpecialTypes <= (int)SpecialType.Count);
Debug.Assert(_cachedSpecialTypes > 0 && _cachedSpecialTypes < (int)InternalSpecialType.NextAvailable);
}
}

Expand All @@ -112,7 +112,7 @@ internal override bool KeepLookingForDeclaredSpecialTypes
{
get
{
return ReferenceEquals(this.CorLibrary, this) && _cachedSpecialTypes < (int)SpecialType.Count;
return ReferenceEquals(this.CorLibrary, this) && _cachedSpecialTypes < (int)InternalSpecialType.NextAvailable - 1;
}
}

Expand Down Expand Up @@ -202,7 +202,7 @@ internal override Symbol GetDeclaredSpecialTypeMember(SpecialMember member)
}

var descriptor = SpecialMembers.GetDescriptor(member);
NamedTypeSymbol type = GetDeclaredSpecialType((SpecialType)descriptor.DeclaringTypeId);
NamedTypeSymbol type = GetDeclaredSpecialType(descriptor.DeclaringSpecialType);
Symbol result = null;

if (!type.IsErrorType())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ internal override NamedTypeSymbol LookupDeclaredOrForwardedTopLevelMetadataType(

#nullable disable

internal override NamedTypeSymbol GetDeclaredSpecialType(SpecialType type)
internal override NamedTypeSymbol GetDeclaredSpecialType(ExtendedSpecialType type)
{
throw ExceptionUtilities.Unreachable();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ internal override TypeConversions TypeConversions
/// called if it is know that this is the Cor Library (mscorlib).
/// </summary>
/// <param name="type"></param>
internal override NamedTypeSymbol GetDeclaredSpecialType(SpecialType type)
internal override NamedTypeSymbol GetDeclaredSpecialType(ExtendedSpecialType type)
{
#if DEBUG
foreach (var module in this.Modules)
Expand All @@ -69,7 +69,7 @@ internal override NamedTypeSymbol GetDeclaredSpecialType(SpecialType type)
if (_lazySpecialTypes == null)
{
Interlocked.CompareExchange(ref _lazySpecialTypes,
new NamedTypeSymbol[(int)SpecialType.Count + 1], null);
new NamedTypeSymbol[(int)InternalSpecialType.NextAvailable], null);
}

if ((object)_lazySpecialTypes[(int)type] == null)
Expand Down
Loading