未验证 提交 cd07ae3d 编写于 作者: J Jared Parsons 提交者: GitHub

Merge pull request #30761 from AlekseyTs/dev16.0.x

Merge 'features/NullableReferenceTypes' into 'dev16.0.x'
......@@ -19,9 +19,9 @@ internal sealed class NonNullTypesTrueContext : INonNullTypesContext
public bool? NonNullTypes => true;
}
internal sealed class NonNullTypesFalseContext : INonNullTypesContext
internal sealed class NonNullTypesNullContext : INonNullTypesContext
{
public static readonly INonNullTypesContext Instance = new NonNullTypesFalseContext();
public bool? NonNullTypes => false;
public static readonly INonNullTypesContext Instance = new NonNullTypesNullContext();
public bool? NonNullTypes => null;
}
}
......@@ -2490,7 +2490,7 @@ private bool Fix(int iParam, ref bool hadNullabilityMismatch, ref HashSet<Diagno
{
if (!_conversions.IncludeNullability)
{
return false;
return null;
}
return _getIsNullableOpt?.Invoke(expr);
}
......
......@@ -604,7 +604,7 @@ private BoundLambda ReallyInferReturnType(NamedTypeSymbol delegateType, Immutabl
var returnType = inferredReturnType.Type;
if (returnType.IsNull)
{
returnType = TypeSymbolWithAnnotations.Create(NonNullTypesFalseContext.Instance, LambdaSymbol.InferenceFailureReturnType);
returnType = TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, LambdaSymbol.InferenceFailureReturnType);
}
lambdaSymbol.SetInferredReturnType(inferredReturnType.RefKind, returnType);
......
......@@ -48,7 +48,10 @@ void Cci.IReference.Dispatch(Cci.MetadataVisitor visitor)
/// </summary>
internal bool IsDefinitionOrDistinct()
{
return this.IsDefinition || !this.Equals(this.OriginalDefinition);
return this.IsDefinition ||
!(this is NamedTypeSymbol namedTypeSymbol ?
namedTypeSymbol.Equals(namedTypeSymbol.OriginalDefinition, TypeCompareKind.CompareNullableModifiersForReferenceTypes) :
this.Equals(this.OriginalDefinition));
}
IEnumerable<Cci.ICustomAttribute> Cci.IReference.GetAttributes(EmitContext context)
......
......@@ -55,7 +55,6 @@ internal sealed class SynthesizedClosureMethod : SynthesizedMethodBaseSymbol, IS
typeMap = lambdaFrame.TypeMap.WithConcatAlphaRename(
originalMethod,
this,
nonNullTypesContext: originalMethod,
out typeParameters,
out constructedFromTypeParameters,
lambdaFrame.OriginalContainingMethodOpt);
......@@ -66,7 +65,6 @@ internal sealed class SynthesizedClosureMethod : SynthesizedMethodBaseSymbol, IS
typeMap = TypeMap.Empty.WithConcatAlphaRename(
originalMethod,
this,
nonNullTypesContext: originalMethod,
out typeParameters,
out constructedFromTypeParameters,
stopAt: null);
......
......@@ -664,7 +664,7 @@ internal BaseMethodWrapperSymbol(NamedTypeSymbol containingType, MethodSymbol me
}
else
{
typeMap = typeMap.WithAlphaRename(methodBeingWrapped, this, nonNullTypesContext: NonNullTypesTrueContext.Instance, out typeParameters);
typeMap = typeMap.WithAlphaRename(methodBeingWrapped, this, out typeParameters);
}
AssignTypeMapAndTypeParameters(typeMap, typeParameters);
......
......@@ -125,8 +125,7 @@ internal TypeSymbolWithAnnotations SubstituteType(TypeSymbol previous)
break;
}
// https://github.com/dotnet/roslyn/issues/30072: we're dropping annotation and context
return TypeSymbolWithAnnotations.Create(result);
return TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, result);
}
internal TypeSymbolWithAnnotations SubstituteType(TypeSymbolWithAnnotations previous)
......@@ -198,7 +197,7 @@ protected virtual TypeSymbol SubstituteDynamicType()
protected virtual TypeSymbolWithAnnotations SubstituteTypeParameter(TypeParameterSymbol typeParameter)
{
return TypeSymbolWithAnnotations.Create(typeParameter);
return TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, typeParameter);
}
private ArrayTypeSymbol SubstituteArrayType(ArrayTypeSymbol t)
......
......@@ -29,7 +29,7 @@ protected sealed override TypeSymbolWithAnnotations SubstituteTypeParameter(Type
return result;
}
return TypeSymbolWithAnnotations.Create(typeParameter);
return TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, typeParameter);
}
private string GetDebuggerDisplay()
......
......@@ -1069,7 +1069,17 @@ protected override bool MatchArrayRank(TypeSymbol type, int countOfDimensions)
protected override bool MatchTypeToTypeId(TypeSymbol type, int typeId)
{
return (int)type.SpecialType == typeId;
if ((int)type.OriginalDefinition.SpecialType == typeId)
{
if (type.IsDefinition)
{
return true;
}
return type == type.OriginalDefinition;
}
return false;
}
}
......
......@@ -1198,7 +1198,7 @@ public static bool RequiresChecking(NamedTypeSymbol type)
return false;
}
Debug.Assert(type.ConstructedFrom != type);
Debug.Assert(!type.ConstructedFrom.Equals(type, TypeCompareKind.CompareNullableModifiersForReferenceTypes));
return true;
}
......
......@@ -37,9 +37,9 @@ internal abstract partial class ErrorTypeSymbol : NamedTypeSymbol, IErrorTypeSym
/// to perform substitution on the wrapped type, if any, and then construct a new
/// error type symbol from the result (if there was a change).
/// </summary>
internal virtual TypeSymbolWithAnnotations Substitute(AbstractTypeMap typeMap)
internal TypeSymbolWithAnnotations Substitute(AbstractTypeMap typeMap)
{
return TypeSymbolWithAnnotations.Create((ErrorTypeSymbol)typeMap.SubstituteNamedType(this));
return TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, (ErrorTypeSymbol)typeMap.SubstituteNamedType(this));
}
/// <summary>
......@@ -645,7 +645,7 @@ internal sealed class SubstitutedNestedErrorTypeSymbol : SubstitutedErrorTypeSym
base(originalDefinition)
{
_containingSymbol = containingSymbol;
_map = containingSymbol.TypeSubstitution.WithAlphaRename(originalDefinition, this, nonNullTypesContext: originalDefinition, out _typeParameters);
_map = containingSymbol.TypeSubstitution.WithAlphaRename(originalDefinition, this, out _typeParameters);
}
public override ImmutableArray<TypeParameterSymbol> TypeParameters
......
......@@ -257,7 +257,7 @@ internal EventSymbol AsMember(NamedTypeSymbol newOwner)
{
Debug.Assert(this.IsDefinition);
Debug.Assert(ReferenceEquals(newOwner.OriginalDefinition, this.ContainingSymbol.OriginalDefinition));
return (newOwner == this.ContainingSymbol) ? this : new SubstitutedEventSymbol(newOwner as SubstitutedNamedTypeSymbol, this);
return newOwner.IsDefinition ? this : new SubstitutedEventSymbol(newOwner as SubstitutedNamedTypeSymbol, this);
}
internal abstract bool MustCallMethodsDirectly { get; }
......
......@@ -314,7 +314,7 @@ internal FieldSymbol AsMember(NamedTypeSymbol newOwner)
{
Debug.Assert(this.IsDefinition);
Debug.Assert(ReferenceEquals(newOwner.OriginalDefinition, this.ContainingSymbol.OriginalDefinition));
return (newOwner == this.ContainingSymbol) ? this : new SubstitutedFieldSymbol(newOwner as SubstitutedNamedTypeSymbol, this);
return newOwner.IsDefinition ? this : new SubstitutedFieldSymbol(newOwner as SubstitutedNamedTypeSymbol, this);
}
#region Use-Site Diagnostics
......
......@@ -420,8 +420,8 @@ public bool Equals(Symbol member1, Symbol member2)
var indexed = builder.ToImmutableAndFree();
typeMap1 = new TypeMap(nonNullTypesContext: member1.OriginalDefinition, member1.GetMemberTypeParameters(), indexed, true);
typeMap2 = new TypeMap(nonNullTypesContext: member2.OriginalDefinition, typeParameters2, indexed, true);
typeMap1 = new TypeMap(member1.GetMemberTypeParameters(), indexed, true);
typeMap2 = new TypeMap(typeParameters2, indexed, true);
}
else
{
......@@ -589,7 +589,6 @@ private static TypeMap GetTypeMap(Symbol member)
return typeParameters.IsEmpty ?
null :
new TypeMap(
nonNullTypesContext: member.OriginalDefinition,
typeParameters,
IndexedTypeParameterSymbol.Take(member.GetMemberArity()),
true);
......
......@@ -223,7 +223,6 @@ private static bool MethodSymbolMatchesParamInfo(MethodSymbol candidateMethod, P
// IndexedTypeParameterSymbol is not going to be exposed anywhere,
// so we'll cheat and use it here for comparison purposes.
TypeMap candidateMethodTypeMap = new TypeMap(
nonNullTypesContext: NonNullTypesFalseContext.Instance, // The NonNullType context doesn't really matter here, because nullability of reference types is not considered for the purpose of the method.
candidateMethod.TypeParameters,
IndexedTypeParameterSymbol.Take(candidateMethod.Arity), true);
......
......@@ -2441,8 +2441,8 @@ private bool MatchesContainingTypeParameters()
// containing symbol for the temporary type is the namespace directly.
var nestedType = Create(this.ContainingPEModule, (PENamespaceSymbol)this.ContainingNamespace, _handle, null);
var nestedTypeParameters = nestedType.TypeParameters;
var containingTypeMap = new TypeMap(nonNullTypesContext: container, containingTypeParameters, IndexedTypeParameterSymbol.Take(n), allowAlpha: false);
var nestedTypeMap = new TypeMap(nonNullTypesContext: nestedType, nestedTypeParameters, IndexedTypeParameterSymbol.Take(nestedTypeParameters.Length), allowAlpha: false);
var containingTypeMap = new TypeMap(containingTypeParameters, IndexedTypeParameterSymbol.Take(n), allowAlpha: false);
var nestedTypeMap = new TypeMap(nestedTypeParameters, IndexedTypeParameterSymbol.Take(nestedTypeParameters.Length), allowAlpha: false);
for (int i = 0; i < n; i++)
{
......
......@@ -174,7 +174,7 @@ private static TypeSymbolWithAnnotations CreateType(TypeSymbol type, ImmutableAr
{
// NonNullTypesContext is unset because the actual context will
// be set when these types are transformed by the caller.
return TypeSymbolWithAnnotations.Create(NonNullTypesFalseContext.Instance, type, customModifiers: CSharpCustomModifier.Convert(customModifiers));
return TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, type, customModifiers: CSharpCustomModifier.Convert(customModifiers));
}
}
}
......@@ -219,16 +219,9 @@ public bool ReturnsByRefReadonly
internal ImmutableArray<TypeSymbolWithAnnotations> GetTypeParametersAsTypeArguments()
{
// Resolving [NonNullTypes] only makes sense within the definition of the generic type or method.
// If this is a substituted symbol, we use a dummy NonNullTypes context.
var definition = OriginalDefinition;
INonNullTypesContext nonNullTypesContext = (object)this == definition ? definition : NonNullTypesFalseContext.Instance;
return GetTypeParametersAsTypeArguments(nonNullTypesContext);
return TypeMap.TypeParametersAsTypeSymbolsWithAnnotations(TypeParameters);
}
internal ImmutableArray<TypeSymbolWithAnnotations> GetTypeParametersAsTypeArguments(INonNullTypesContext nonNullTypesContext) =>
TypeMap.TypeParametersAsTypeSymbolsWithAnnotations(nonNullTypesContext, TypeParameters);
/// <summary>
/// Call <see cref="TryGetThisParameter"/> and throw if it returns false.
/// </summary>
......@@ -794,7 +787,7 @@ internal MethodSymbol AsMember(NamedTypeSymbol newOwner)
{
Debug.Assert(this.IsDefinition);
Debug.Assert(ReferenceEquals(newOwner.OriginalDefinition, this.ContainingSymbol.OriginalDefinition));
return (newOwner == this.ContainingSymbol) ? this : new SubstitutedMethodSymbol(newOwner, this);
return newOwner.IsDefinition ? this : new SubstitutedMethodSymbol(newOwner, this);
}
/// <summary>
......
......@@ -674,8 +674,17 @@ internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison)
var thisOriginalDefinition = this.OriginalDefinition;
var otherOriginalDefinition = other.OriginalDefinition;
if (((object)this == (object)thisOriginalDefinition || (object)other == (object)otherOriginalDefinition) &&
(comparison & TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds) == 0)
bool thisIsOriginalDefinition = ((object)this == (object)thisOriginalDefinition);
bool otherIsOriginalDefinition = ((object)other == (object)otherOriginalDefinition);
if (thisIsOriginalDefinition && otherIsOriginalDefinition)
{
// If we continue, we either return false, or get into a cycle.
return false;
}
if ((thisIsOriginalDefinition || otherIsOriginalDefinition) &&
(comparison & (TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.CompareNullableModifiersForReferenceTypes)) == TypeCompareKind.CompareNullableModifiersForReferenceTypes)
{
return false;
}
......@@ -718,9 +727,13 @@ private bool EqualsComplicatedCases(NamedTypeSymbol other, TypeCompareKind compa
return true;
}
if (((thisIsNotConstructed || otherIsNotConstructed) &&
(comparison & TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds) == 0) ||
this.IsUnboundGenericType != other.IsUnboundGenericType)
if (this.IsUnboundGenericType != other.IsUnboundGenericType)
{
return false;
}
if ((thisIsNotConstructed || otherIsNotConstructed) &&
(comparison & (TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.CompareNullableModifiersForReferenceTypes)) == TypeCompareKind.CompareNullableModifiersForReferenceTypes)
{
return false;
}
......@@ -950,7 +963,7 @@ private static VarianceKind GetTypeArgumentVariance(VarianceKind typeVariance, V
public NamedTypeSymbol Construct(params TypeSymbol[] typeArguments)
{
// https://github.com/dotnet/roslyn/issues/30064: We should fix the callers to pass an explicit context.
return ConstructWithoutModifiers(typeArguments.AsImmutableOrNull(), false, NonNullTypesFalseContext.Instance);
return ConstructWithoutModifiers(typeArguments.AsImmutableOrNull(), false, NonNullTypesNullContext.Instance);
}
/// <summary>
......@@ -972,7 +985,7 @@ public NamedTypeSymbol Construct(INonNullTypesContext nonNullTypesContext, param
public NamedTypeSymbol Construct(ImmutableArray<TypeSymbol> typeArguments, INonNullTypesContext nonNullTypesContext = null)
{
// https://github.com/dotnet/roslyn/issues/30064: We should fix the callers to pass an explicit context.
return ConstructWithoutModifiers(typeArguments, false, nonNullTypesContext ?? NonNullTypesFalseContext.Instance);
return ConstructWithoutModifiers(typeArguments, false, nonNullTypesContext ?? NonNullTypesNullContext.Instance);
}
/// <summary>
......@@ -982,7 +995,7 @@ public NamedTypeSymbol Construct(ImmutableArray<TypeSymbol> typeArguments, INonN
public NamedTypeSymbol Construct(IEnumerable<TypeSymbol> typeArguments)
{
// https://github.com/dotnet/roslyn/issues/30064: We should fix the callers to pass an explicit context.
return ConstructWithoutModifiers(typeArguments.AsImmutableOrNull(), false, NonNullTypesFalseContext.Instance);
return ConstructWithoutModifiers(typeArguments.AsImmutableOrNull(), false, NonNullTypesNullContext.Instance);
}
/// <summary>
......@@ -1164,9 +1177,7 @@ internal int AllTypeArgumentCount()
internal ImmutableArray<TypeSymbolWithAnnotations> GetTypeParametersAsTypeArguments()
{
// https://github.com/dotnet/roslyn/issues/30068: Set IsNullable=null always, even in C#8,
// and set TypeSymbolWithAnnotations.WithCustomModifiers.Is() => false.
return this.TypeParameters.SelectAsArray((typeParameter, module) => TypeSymbolWithAnnotations.Create(nonNullTypesContext: module, typeParameter), ContainingModule);
return TypeMap.TypeParametersAsTypeSymbolsWithAnnotations(this.TypeParameters);
}
/// <summary>
......
......@@ -332,7 +332,7 @@ internal PropertySymbol AsMember(NamedTypeSymbol newOwner)
{
Debug.Assert(this.IsDefinition);
Debug.Assert(ReferenceEquals(newOwner.OriginalDefinition, this.ContainingSymbol.OriginalDefinition));
return (newOwner == this.ContainingSymbol) ? this : new SubstitutedPropertySymbol(newOwner as SubstitutedNamedTypeSymbol, this);
return newOwner.IsDefinition ? this : new SubstitutedPropertySymbol(newOwner as SubstitutedNamedTypeSymbol, this);
}
#region Use-Site Diagnostics
......
......@@ -92,7 +92,7 @@ private ReducedExtensionMethodSymbol(MethodSymbol reducedFrom)
Debug.Assert(reducedFrom.ParameterCount > 0);
_reducedFrom = reducedFrom;
_typeMap = TypeMap.Empty.WithAlphaRename(reducedFrom, this, nonNullTypesContext: reducedFrom, out _typeParameters);
_typeMap = TypeMap.Empty.WithAlphaRename(reducedFrom, this, out _typeParameters);
_typeArguments = _typeMap.SubstituteTypes(reducedFrom.TypeArguments);
}
......
......@@ -47,7 +47,7 @@ internal sealed class LambdaSymbol : SourceMethodSymbol
_messageID = unboundLambda.Data.MessageID;
_syntax = unboundLambda.Syntax;
_refKind = refKind;
_returnType = returnType.IsNull ? TypeSymbolWithAnnotations.Create(NonNullTypesFalseContext.Instance, ReturnTypeIsBeingInferred) : returnType;
_returnType = returnType.IsNull ? TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, ReturnTypeIsBeingInferred) : returnType;
_isSynthesized = unboundLambda.WasCompilerGenerated;
_isAsync = unboundLambda.IsAsync;
// No point in making this lazy. We are always going to need these soon after creation of the symbol.
......
......@@ -1116,8 +1116,8 @@ private static bool HaveSameConstraints(SourceOrdinaryMethodSymbol part1, Source
var typeParameters2 = part2.TypeParameters;
var indexedTypeParameters = IndexedTypeParameterSymbol.Take(arity);
var typeMap1 = new TypeMap(nonNullTypesContext: part1, typeParameters1, indexedTypeParameters, allowAlpha: true);
var typeMap2 = new TypeMap(nonNullTypesContext: part1, typeParameters2, indexedTypeParameters, allowAlpha: true);
var typeMap1 = new TypeMap(typeParameters1, indexedTypeParameters, allowAlpha: true);
var typeMap2 = new TypeMap(typeParameters2, indexedTypeParameters, allowAlpha: true);
return MemberSignatureComparer.HaveSameConstraints(typeParameters1, typeMap1, typeParameters2, typeMap2);
}
......
......@@ -662,7 +662,7 @@ public TypeMap TypeMap
Debug.Assert(overriddenTypeParameters.Length == overridingTypeParameters.Length);
var typeMap = new TypeMap(nonNullTypesContext: _overridingMethod, overriddenTypeParameters, overridingTypeParameters, allowAlpha: true);
var typeMap = new TypeMap(overriddenTypeParameters, overridingTypeParameters, allowAlpha: true);
Interlocked.CompareExchange(ref _lazyTypeMap, typeMap, null);
}
}
......
......@@ -105,7 +105,7 @@ private void EnsureMapAndTypeParameters()
Debug.Assert(ReferenceEquals(_constructedFrom, this));
// We're creating a new unconstructed Method from another; alpha-rename type parameters.
var newMap = _inputMap.WithAlphaRename(this.OriginalDefinition, this, nonNullTypesContext: this.OriginalDefinition, out typeParameters);
var newMap = _inputMap.WithAlphaRename(this.OriginalDefinition, this, out typeParameters);
var prevMap = Interlocked.CompareExchange(ref _lazyMap, newMap, null);
if (prevMap != null)
......
......@@ -100,7 +100,7 @@ private void EnsureMapAndTypeParameters()
ImmutableArray<TypeParameterSymbol> typeParameters;
// We're creating a new unconstructed Method from another; alpha-rename type parameters.
var newMap = _inputMap.WithAlphaRename(OriginalDefinition, this, nonNullTypesContext: OriginalDefinition, out typeParameters);
var newMap = _inputMap.WithAlphaRename(OriginalDefinition, this, out typeParameters);
var prevMap = Interlocked.CompareExchange(ref _lazyMap, newMap, null);
if (prevMap != null)
......
......@@ -39,7 +39,7 @@ protected SynthesizedContainer(string name, MethodSymbol containingMethod)
}
else
{
TypeMap = TypeMap.Empty.WithConcatAlphaRename(containingMethod, this, nonNullTypesContext: containingMethod, out _typeParameters, out _constructedFromTypeParameters);
TypeMap = TypeMap.Empty.WithConcatAlphaRename(containingMethod, this, out _typeParameters, out _constructedFromTypeParameters);
}
}
......
......@@ -41,9 +41,9 @@ internal abstract class SynthesizedImplementationMethod : SynthesizedInstanceMet
// alpha-rename to get the implementation's type parameters
var typeMap = interfaceMethod.ContainingType.TypeSubstitution ?? TypeMap.Empty;
typeMap.WithAlphaRename(interfaceMethod, this, nonNullTypesContext: this, out _typeParameters);
typeMap.WithAlphaRename(interfaceMethod, this, out _typeParameters);
_interfaceMethod = interfaceMethod.ConstructIfGeneric(GetTypeParametersAsTypeArguments(nonNullTypesContext: this));
_interfaceMethod = interfaceMethod.ConstructIfGeneric(TypeArguments);
_parameters = SynthesizedParameterSymbol.DeriveParameters(_interfaceMethod, this);
}
......@@ -88,7 +88,7 @@ public sealed override ImmutableArray<TypeParameterSymbol> TypeParameters
public sealed override ImmutableArray<TypeSymbolWithAnnotations> TypeArguments
{
get { return GetTypeParametersAsTypeArguments(nonNullTypesContext: this); }
get { return GetTypeParametersAsTypeArguments(); }
}
public override RefKind RefKind
......
......@@ -24,8 +24,8 @@ public TupleMethodSymbol(TupleTypeSymbol container, MethodSymbol underlyingMetho
Debug.Assert(underlyingMethod.ConstructedFrom == (object)underlyingMethod);
_containingType = container;
TypeMap.Empty.WithAlphaRename(underlyingMethod, this, nonNullTypesContext: underlyingMethod.OriginalDefinition, out _typeParameters);
_underlyingMethod = underlyingMethod.ConstructIfGeneric(GetTypeParametersAsTypeArguments(nonNullTypesContext: this));
TypeMap.Empty.WithAlphaRename(underlyingMethod, this, out _typeParameters);
_underlyingMethod = underlyingMethod.ConstructIfGeneric(TypeArguments);
}
public override bool IsTupleMethod
......@@ -130,7 +130,7 @@ public override ImmutableArray<TypeSymbolWithAnnotations> TypeArguments
{
get
{
return GetTypeParametersAsTypeArguments(nonNullTypesContext: this);
return GetTypeParametersAsTypeArguments();
}
}
......
......@@ -18,11 +18,11 @@ internal sealed class TypeMap : AbstractTypeParameterMap
{
public static readonly System.Func<TypeSymbolWithAnnotations, TypeSymbol> AsTypeSymbol = t => t.TypeSymbol;
internal static ImmutableArray<TypeSymbolWithAnnotations> TypeParametersAsTypeSymbolsWithAnnotations(INonNullTypesContext nonNullTypesContext, ImmutableArray<TypeParameterSymbol> typeParameters)
internal static ImmutableArray<TypeSymbolWithAnnotations> TypeParametersAsTypeSymbolsWithAnnotations(ImmutableArray<TypeParameterSymbol> typeParameters)
{
return typeParameters.SelectAsArray((tp, c) =>
TypeSymbolWithAnnotations.Create(nonNullTypesContext: c, tp, isAnnotated: false, customModifiers: ImmutableArray<CustomModifier>.Empty),
nonNullTypesContext);
return typeParameters.SelectAsArray((tp) =>
TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, tp, isAnnotated: false, customModifiers: ImmutableArray<CustomModifier>.Empty)
);
}
internal static ImmutableArray<TypeSymbol> AsTypeSymbols(ImmutableArray<TypeSymbolWithAnnotations> typesOpt)
......@@ -39,8 +39,8 @@ internal TypeMap(ImmutableArray<TypeParameterSymbol> from, ImmutableArray<TypeSy
}
// Only when the caller passes allowAlpha=true do we tolerate substituted (alpha-renamed) type parameters as keys
internal TypeMap(INonNullTypesContext nonNullTypesContext, ImmutableArray<TypeParameterSymbol> from, ImmutableArray<TypeParameterSymbol> to, bool allowAlpha = false)
: this(from, TypeParametersAsTypeSymbolsWithAnnotations(nonNullTypesContext, to), allowAlpha)
internal TypeMap(ImmutableArray<TypeParameterSymbol> from, ImmutableArray<TypeParameterSymbol> to, bool allowAlpha = false)
: this(from, TypeParametersAsTypeSymbolsWithAnnotations(to), allowAlpha)
{
// mapping contents are read-only hereafter
}
......@@ -92,7 +92,7 @@ public static TypeMap Empty
}
}
private TypeMap WithAlphaRename(ImmutableArray<TypeParameterSymbol> oldTypeParameters, Symbol newOwner, INonNullTypesContext nonNullTypesContext, out ImmutableArray<TypeParameterSymbol> newTypeParameters)
private TypeMap WithAlphaRename(ImmutableArray<TypeParameterSymbol> oldTypeParameters, Symbol newOwner, out ImmutableArray<TypeParameterSymbol> newTypeParameters)
{
if (oldTypeParameters.Length == 0)
{
......@@ -119,7 +119,7 @@ private TypeMap WithAlphaRename(ImmutableArray<TypeParameterSymbol> oldTypeParam
var newTp = synthesized ?
new SynthesizedSubstitutedTypeParameterSymbol(newOwner, result, tp, ordinal) :
new SubstitutedTypeParameterSymbol(newOwner, result, tp, ordinal);
result.Mapping.Add(tp, TypeSymbolWithAnnotations.Create(nonNullTypesContext, newTp));
result.Mapping.Add(tp, TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, newTp));
newTypeParametersBuilder.Add(newTp);
ordinal++;
}
......@@ -128,22 +128,21 @@ private TypeMap WithAlphaRename(ImmutableArray<TypeParameterSymbol> oldTypeParam
return result;
}
internal TypeMap WithAlphaRename(NamedTypeSymbol oldOwner, NamedTypeSymbol newOwner, INonNullTypesContext nonNullTypesContext, out ImmutableArray<TypeParameterSymbol> newTypeParameters)
internal TypeMap WithAlphaRename(NamedTypeSymbol oldOwner, NamedTypeSymbol newOwner, out ImmutableArray<TypeParameterSymbol> newTypeParameters)
{
Debug.Assert(oldOwner.ConstructedFrom == oldOwner);
return WithAlphaRename(oldOwner.OriginalDefinition.TypeParameters, newOwner, nonNullTypesContext, out newTypeParameters);
return WithAlphaRename(oldOwner.OriginalDefinition.TypeParameters, newOwner, out newTypeParameters);
}
internal TypeMap WithAlphaRename(MethodSymbol oldOwner, Symbol newOwner, INonNullTypesContext nonNullTypesContext, out ImmutableArray<TypeParameterSymbol> newTypeParameters)
internal TypeMap WithAlphaRename(MethodSymbol oldOwner, Symbol newOwner, out ImmutableArray<TypeParameterSymbol> newTypeParameters)
{
Debug.Assert(oldOwner.ConstructedFrom == oldOwner);
return WithAlphaRename(oldOwner.OriginalDefinition.TypeParameters, newOwner, nonNullTypesContext, out newTypeParameters);
return WithAlphaRename(oldOwner.OriginalDefinition.TypeParameters, newOwner, out newTypeParameters);
}
internal TypeMap WithConcatAlphaRename(
MethodSymbol oldOwner,
Symbol newOwner,
INonNullTypesContext nonNullTypesContext,
out ImmutableArray<TypeParameterSymbol> newTypeParameters,
out ImmutableArray<TypeParameterSymbol> oldTypeParameters,
MethodSymbol stopAt = null)
......@@ -187,7 +186,7 @@ internal TypeMap WithAlphaRename(MethodSymbol oldOwner, Symbol newOwner, INonNul
stopAt?.MethodKind == MethodKind.Constructor);
oldTypeParameters = parameters.ToImmutableAndFree();
return WithAlphaRename(oldTypeParameters, newOwner, nonNullTypesContext, out newTypeParameters);
return WithAlphaRename(oldTypeParameters, newOwner, out newTypeParameters);
}
private static SmallDictionary<TypeParameterSymbol, TypeSymbolWithAnnotations> ConstructMapping(ImmutableArray<TypeParameterSymbol> from, ImmutableArray<TypeSymbolWithAnnotations> to)
......
......@@ -1293,8 +1293,8 @@ private static bool ReportAnyMismatchedConstraints(MethodSymbol interfaceMethod,
var typeParameters2 = implicitImpl.TypeParameters;
var indexedTypeParameters = IndexedTypeParameterSymbol.Take(arity);
var typeMap1 = new TypeMap(nonNullTypesContext: interfaceMethod.OriginalDefinition, typeParameters1, indexedTypeParameters, allowAlpha: true);
var typeMap2 = new TypeMap(nonNullTypesContext: implicitImpl.OriginalDefinition, typeParameters2, indexedTypeParameters, allowAlpha: true);
var typeMap1 = new TypeMap(typeParameters1, indexedTypeParameters, allowAlpha: true);
var typeMap2 = new TypeMap(typeParameters2, indexedTypeParameters, allowAlpha: true);
// Report any mismatched method constraints.
for (int i = 0; i < arity; i++)
......
......@@ -184,7 +184,7 @@ public static TypeSymbolWithAnnotations Create(TypeSymbol typeSymbol, bool? isNu
return default;
}
var context = isNullableIfReferenceType == null ? NonNullTypesFalseContext.Instance : NonNullTypesTrueContext.Instance;
var context = isNullableIfReferenceType == null ? NonNullTypesNullContext.Instance : NonNullTypesTrueContext.Instance;
bool isAnnotated = isNullableIfReferenceType == true;
bool treatPossiblyNullableReferenceTypeTypeParameterAsNullable = false;
......@@ -515,37 +515,83 @@ public bool IsAtLeastAsVisibleAs(Symbol sym, ref HashSet<DiagnosticInfo> useSite
internal TypeSymbolWithAnnotations SubstituteTypeCore(AbstractTypeMap typeMap, bool withTupleUnification)
{
var newCustomModifiers = typeMap.SubstituteCustomModifiers(this.CustomModifiers);
var newTypeWithModifiers = typeMap.SubstituteType(this.TypeSymbol, withTupleUnification);
bool newIsAnnotated = this.IsAnnotated || newTypeWithModifiers.IsAnnotated;
TypeSymbol typeSymbol = this.TypeSymbol;
var newTypeWithModifiers = typeMap.SubstituteType(typeSymbol, withTupleUnification);
if (!typeSymbol.IsTypeParameter())
{
Debug.Assert(newTypeWithModifiers.IsAnnotated == false || typeSymbol.IsNullableType());
Debug.Assert(newTypeWithModifiers.NonNullTypesContext.NonNullTypes == null);
Debug.Assert(newTypeWithModifiers.CustomModifiers.IsEmpty);
if (typeSymbol.Equals(newTypeWithModifiers.TypeSymbol, TypeCompareKind.CompareNullableModifiersForReferenceTypes) &&
newCustomModifiers == CustomModifiers)
{
return this; // substitution had no effect on the type or modifiers
}
else if (IsAnnotated == false &&
NonNullTypesContext.NonNullTypes == null &&
newCustomModifiers.IsEmpty)
{
return newTypeWithModifiers;
}
// https://github.com/dotnet/roslyn/issues/30052: Can we use Equals instead?
if (this.TypeSymbolEquals(newTypeWithModifiers, TypeCompareKind.CompareNullableModifiersForReferenceTypes) &&
newTypeWithModifiers.CustomModifiers.IsEmpty &&
newIsAnnotated == this.IsAnnotated &&
newCustomModifiers == this.CustomModifiers)
return Create(NonNullTypesContext, newTypeWithModifiers.TypeSymbol, IsAnnotated, newCustomModifiers);
}
if (newTypeWithModifiers.Is((TypeParameterSymbol)typeSymbol) &&
newCustomModifiers == CustomModifiers)
{
// https://github.com/dotnet/roslyn/issues/30052: We're dropping newTypeWithModifiers.NonNullTypes!
return this; // substitution had no effect on the type or modifiers
}
else if(Is((TypeParameterSymbol)typeSymbol))
{
return newTypeWithModifiers;
}
bool newIsAnnotated = this.IsAnnotated || newTypeWithModifiers.IsAnnotated;
INonNullTypesContext newContext;
bool newIsNullableType = newTypeWithModifiers.TypeSymbol.IsNullableType();
if (newIsNullableType)
if (!newIsAnnotated)
{
if (newCustomModifiers.IsEmpty)
if (NonNullTypesContext.NonNullTypes == true)
{
return newTypeWithModifiers;
if (IsIndexedTypeParameter(newTypeWithModifiers.TypeSymbol) || !typeSymbol.IsUnconstrainedTypeParameter())
{
newContext = NonNullTypesContext;
}
else
{
newContext = newTypeWithModifiers.NonNullTypesContext;
}
}
else if (newTypeWithModifiers.NonNullTypesContext.NonNullTypes == true)
{
newContext = newTypeWithModifiers.NonNullTypesContext;
}
else if (NonNullTypesContext.NonNullTypes == null)
{
newContext = newTypeWithModifiers.NonNullTypesContext;
}
else if (newTypeWithModifiers.NonNullTypesContext.NonNullTypes == null)
{
newContext = NonNullTypesContext;
}
else
{
Debug.Assert(NonNullTypesContext.NonNullTypes == false);
Debug.Assert(newTypeWithModifiers.NonNullTypesContext.NonNullTypes == false);
newContext = NonNullTypesContext;
}
newIsAnnotated = newTypeWithModifiers.IsAnnotated;
Debug.Assert(newIsAnnotated);
}
else if (newCustomModifiers.IsEmpty && newTypeWithModifiers.IsAnnotated == newIsAnnotated)
else
{
return newTypeWithModifiers;
newContext = newTypeWithModifiers.NonNullTypesContext;
}
return CreateNonLazyType(
newTypeWithModifiers.TypeSymbol,
newTypeWithModifiers.NonNullTypesContext,
newContext,
isAnnotated: newIsAnnotated,
newTypeWithModifiers._treatPossiblyNullableReferenceTypeTypeParameterAsNullable,
newCustomModifiers.Concat(newTypeWithModifiers.CustomModifiers));
......@@ -573,7 +619,11 @@ internal void ReportDiagnosticsIfObsoleteCore(Binder binder, SyntaxNode syntax,
/// <summary>
/// Is this the given type parameter?
/// </summary>
public bool Is(TypeParameterSymbol other) => _extensions.Is(_defaultType, other);
public bool Is(TypeParameterSymbol other)
{
return !IsAnnotated && NonNullTypesContext.NonNullTypes == null && ((object)_defaultType == other) &&
CustomModifiers.IsEmpty;
}
public TypeSymbolWithAnnotations WithTypeAndModifiers(TypeSymbol typeSymbol, ImmutableArray<CustomModifier> customModifiers) =>
_extensions.WithTypeAndModifiers(this, typeSymbol, customModifiers);
......@@ -688,7 +738,7 @@ public TypeSymbolWithAnnotations SetUnknownNullabilityForReferenceTypes()
{
typeSymbol = typeSymbol.SetUnknownNullabilityForReferenceTypes();
return CreateNonLazyType(typeSymbol, NonNullTypesFalseContext.Instance, isAnnotated: false,
return CreateNonLazyType(typeSymbol, NonNullTypesNullContext.Instance, isAnnotated: false,
treatPossiblyNullableReferenceTypeTypeParameterAsNullable: false, CustomModifiers);
}
}
......@@ -791,8 +841,6 @@ internal static Extensions CreateLazy(CSharpCompilation compilation, TypeSymbolW
internal abstract bool IsVoid(TypeSymbol typeSymbol);
internal abstract bool IsSZArray(TypeSymbol typeSymbol);
internal abstract bool Is(TypeSymbol typeSymbol, TypeParameterSymbol other);
internal abstract TypeSymbolWithAnnotations WithTypeAndModifiers(TypeSymbolWithAnnotations type, TypeSymbol typeSymbol, ImmutableArray<CustomModifier> customModifiers);
internal abstract bool TypeSymbolEquals(TypeSymbolWithAnnotations type, TypeSymbolWithAnnotations other, TypeCompareKind comparison);
......@@ -855,11 +903,6 @@ internal override TypeSymbolWithAnnotations WithNonNullTypesContext(TypeSymbolWi
internal override TypeSymbol AsTypeSymbolOnly(TypeSymbol typeSymbol) => typeSymbol;
// https://github.com/dotnet/roslyn/issues/30054: Use WithCustomModifiers.Is() => false
// and set IsNullable=null always for GetTypeParametersAsTypeArguments.
internal override bool Is(TypeSymbol typeSymbol, TypeParameterSymbol other) =>
typeSymbol.Equals(other, TypeCompareKind.CompareNullableModifiersForReferenceTypes) && _customModifiers.IsEmpty;
internal override TypeSymbolWithAnnotations WithTypeAndModifiers(TypeSymbolWithAnnotations type, TypeSymbol typeSymbol, ImmutableArray<CustomModifier> customModifiers)
{
return CreateNonLazyType(typeSymbol, type.NonNullTypesContext, isAnnotated: type.IsAnnotated,
......@@ -895,7 +938,7 @@ internal override TypeSymbolWithAnnotations TransformToTupleIfCompatible(TypeSym
var transformedType = TupleTypeSymbol.TransformToTupleIfCompatible(defaultType);
if ((object)defaultType != transformedType)
{
return TypeSymbolWithAnnotations.Create(transformedType, type.IsNullable, _customModifiers);
return TypeSymbolWithAnnotations.Create(type.NonNullTypesContext, transformedType, type.IsAnnotated, _customModifiers);
}
return type;
}
......@@ -975,19 +1018,6 @@ internal override TypeSymbol AsTypeSymbolOnly(TypeSymbol typeSymbol)
return resolvedType;
}
// https://github.com/dotnet/roslyn/issues/30054: This implementation looks
// incorrect since a type parameter cannot be Nullable<T>.
internal override bool Is(TypeSymbol typeSymbol, TypeParameterSymbol other)
{
if (!other.IsNullableType())
{
return false;
}
var resolvedType = GetResolvedType();
return resolvedType.Equals(other, TypeCompareKind.CompareNullableModifiersForReferenceTypes);
}
internal override TypeSymbol GetResolvedType(TypeSymbol defaultType) => GetResolvedType();
internal override ImmutableArray<CustomModifier> CustomModifiers => ImmutableArray<CustomModifier>.Empty;
......
......@@ -319,7 +319,7 @@ internal static void VerifyTypes(this CSharpCompilation compilation, SyntaxTree
var expectedTypes = annotations.SelectAsArray(annotation => annotation.Text);
var actualTypes = annotations.SelectAsArray(annotation => toDisplayString(annotation.Expression));
// Consider reporting the correct source with annotations on mismatch.
AssertEx.Equal(expectedTypes, actualTypes);
AssertEx.Equal(expectedTypes, actualTypes, message: method.ToTestDisplayString());
string toDisplayString(SyntaxNode syntaxOpt)
{
......
......@@ -1684,8 +1684,8 @@ private static bool HaveSameConstraints(ImmutableArray<TypeParameterSymbol> cand
}
var indexedTypeParameters = IndexedTypeParameterSymbol.Take(arity);
var candidateTypeMap = new TypeMap(NonNullTypesFalseContext.Instance, candidateTypeParameters, indexedTypeParameters, allowAlpha: true);
var desiredTypeMap = new TypeMap(NonNullTypesFalseContext.Instance, desiredTypeParameters, indexedTypeParameters, allowAlpha: true);
var candidateTypeMap = new TypeMap(candidateTypeParameters, indexedTypeParameters, allowAlpha: true);
var desiredTypeMap = new TypeMap(desiredTypeParameters, indexedTypeParameters, allowAlpha: true);
return MemberSignatureComparer.HaveSameConstraints(candidateTypeParameters, candidateTypeMap, desiredTypeParameters, desiredTypeMap);
}
......
......@@ -97,7 +97,7 @@ internal sealed class EEMethodSymbol : MethodSymbol
(tp, i, arg) => (TypeParameterSymbol)new EETypeParameterSymbol(this, tp, i, getTypeMap),
(object)null);
_allTypeParameters = container.TypeParameters.Concat(_typeParameters);
this.TypeMap = new TypeMap(NonNullTypesFalseContext.Instance, allSourceTypeParameters, _allTypeParameters);
this.TypeMap = new TypeMap(allSourceTypeParameters, _allTypeParameters);
EENamedTypeSymbol.VerifyTypeParameters(this, _typeParameters);
......
......@@ -80,7 +80,7 @@ internal sealed class EENamedTypeSymbol : NamedTypeSymbol
(tp, i, arg) => (TypeParameterSymbol)new EETypeParameterSymbol(this, tp, i, getTypeMap),
(object)null);
typeMap = new TypeMap(nonNullTypesContext: NonNullTypesFalseContext.Instance, this.SourceTypeParameters, _typeParameters);
typeMap = new TypeMap(this.SourceTypeParameters, _typeParameters);
VerifyTypeParameters(this, _typeParameters);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册