Skip to content

Commit

Permalink
Remove incomplete Dictionary<,> suppport
Browse files Browse the repository at this point in the history
  • Loading branch information
cston committed Dec 5, 2024
1 parent 9b378ff commit 5da632a
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 68 deletions.
37 changes: 6 additions & 31 deletions src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -937,26 +937,20 @@ private BoundCollectionExpression ConvertCollectionExpression(
var collectionInitializerAddMethodBinder = new CollectionInitializerAddMethodBinder(syntax, targetType, this);
foreach (var element in elements)
{
BoundNode convertedElement = element switch
{
BoundCollectionExpressionSpreadElement spreadElement => (BoundNode)BindCollectionExpressionSpreadElementAddMethod(
BoundNode convertedElement = element is BoundCollectionExpressionSpreadElement spreadElement ?
(BoundNode)BindCollectionExpressionSpreadElementAddMethod(
(SpreadElementSyntax)spreadElement.Syntax,
spreadElement,
collectionInitializerAddMethodBinder,
implicitReceiver,
diagnostics),
BoundKeyValuePairElement keyValuePairElement => BindKeyValuePairAddMethod(
keyValuePairElement,
implicitReceiver,
diagnostics),
_ => BindCollectionInitializerElementAddMethod(
diagnostics) :
BindCollectionInitializerElementAddMethod(
element.Syntax,
ImmutableArray.Create((BoundExpression)element),
hasEnumerableInitializerType: true,
collectionInitializerAddMethodBinder,
diagnostics,
implicitReceiver)
};
implicitReceiver);
builder.Add(convertedElement);
}
}
Expand Down Expand Up @@ -1202,9 +1196,6 @@ internal bool HasCollectionExpressionApplicableConstructor(SyntaxNode syntax, Ty
var analyzedArguments = AnalyzedArguments.GetInstance();
var binder = new ParamsCollectionTypeInProgressBinder(namedType, this);

// PROTOTYPE: Test with constructor that takes a comparer as well.
// PROTOTYPE: Test the comparer case for non-dictionary collections as well.
// PROTOTYPE: Test the comparer case with/without an explicit comparer in the collection expression.
bool overloadResolutionSucceeded = binder.TryPerformConstructorOverloadResolution(
namedType,
analyzedArguments,
Expand Down Expand Up @@ -1308,29 +1299,13 @@ private bool HasParamsCollectionTypeInProgress(NamedTypeSymbol toCheck,
return false;
}

// PROTOTYPE: This is a simple implementation. What else is needed?
internal bool HasCollectionExpressionApplicableIndexer(SyntaxNode syntax, TypeSymbol targetType, TypeSymbol elementType, out ImmutableArray<PropertySymbol> indexers, BindingDiagnosticBag diagnostics)
{
var lookupResult = LookupResult.GetInstance();
var useSiteInfo = GetNewCompoundUseSiteInfo(diagnostics);
// PROTOTYPE: Test with missing indexer, multiple indexers, readonly/writeonly indexer, different member kind, etc.
// PROTOTYPE: Test with indexer that doesn't match elementType key and value types.
LookupMembersWithFallback(lookupResult, targetType, WellKnownMemberNames.Indexer, arity: 0, ref useSiteInfo);
diagnostics.Add(syntax, useSiteInfo); // PROTOTYPE: Test use-site diagnostics.
indexers = lookupResult.SingleSymbolOrDefault is PropertySymbol property ?
ImmutableArray.Create(property) :
ImmutableArray<PropertySymbol>.Empty;
lookupResult.Free();
return indexers.Length > 0;
}

internal bool HasCollectionExpressionApplicableAddMethod(SyntaxNode syntax, TypeSymbol targetType, out ImmutableArray<MethodSymbol> addMethods, BindingDiagnosticBag diagnostics)
{
Debug.Assert(!targetType.IsDynamic());

NamedTypeSymbol? namedType = targetType as NamedTypeSymbol;

if (namedType is not null && HasParamsCollectionTypeInProgress(namedType, out _, out _)) // PROTOTYPE: Test cycles with params for indexers with dictionary types and non-dictionary types.
if (namedType is not null && HasParamsCollectionTypeInProgress(namedType, out _, out _))
{
// We are in a cycle. Optimistically assume we have the right Add to break the cycle
addMethods = [];
Expand Down
28 changes: 0 additions & 28 deletions src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6518,33 +6518,6 @@ static void copyRelevantAddMethodDiagnostics(BindingDiagnosticBag source, Bindin
}

#nullable enable
// PROTOTYPE: What is the shape of the Add() method for a k:v?
// Does it take two arguments? Or a KeyValuePair<,>? And if a KeyValuePair<,>,
// how do we bind to it so the K and V conversions can be calculated?
private BoundExpression BindKeyValuePairAddMethod(
BoundKeyValuePairElement element,
BoundObjectOrCollectionValuePlaceholder implicitReceiver,
BindingDiagnosticBag diagnostics)
{
// PROTOTYPE: Should use Add rather than indexer for collections that do not have indexers.
// PROTOTYPE: Test with get-only/set-only indexer, inaccessible accessor, etc.
// PROTOTYPE: Test with ref indexer.
var analyzedArguments = AnalyzedArguments.GetInstance();
analyzedArguments.Arguments.Add(element.Key);
var left = BindIndexerAccess(element.Syntax, implicitReceiver, analyzedArguments, diagnostics);
analyzedArguments.Free();
if (left is BoundIndexerAccess indexerAccess)
{
left = indexerAccess.Update(AccessorKind.Set);
}
return BindAssignment(
element.Syntax,
left,
element.Value,
isRef: false,
diagnostics);
}

private BoundCollectionExpressionSpreadElement BindCollectionExpressionSpreadElementAddMethod(
SpreadElementSyntax syntax,
BoundCollectionExpressionSpreadElement element,
Expand All @@ -6567,7 +6540,6 @@ private BoundCollectionExpressionSpreadElement BindCollectionExpressionSpreadEle

Debug.Assert(enumeratorInfo.ElementType is { }); // ElementType is set always, even for IEnumerable.
var addElementPlaceholder = new BoundValuePlaceholder(syntax, enumeratorInfo.ElementType);
// PROTOTYPE: Test when binding to a dictionary type.
var addMethodInvocation = BindCollectionInitializerElementAddMethod(
syntax.Expression,
ImmutableArray.Create((BoundExpression)addElementPlaceholder),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,7 @@ protected override Conversion GetCollectionExpressionConversion(
return Conversion.NoConversion;
}

if ((!ReferenceEquals(elementType.OriginalDefinition, Compilation.GetWellKnownType(WellKnownType.System_Collections_Generic_KeyValuePair_KV)) ||
!_binder.HasCollectionExpressionApplicableIndexer(syntax, targetType, elementType, out _, BindingDiagnosticBag.Discarded)) &&
elements.Length > 0 &&
if (elements.Length > 0 &&
!_binder.HasCollectionExpressionApplicableAddMethod(syntax, targetType, addMethods: out _, BindingDiagnosticBag.Discarded))
{
return Conversion.NoConversion;
Expand All @@ -209,8 +207,7 @@ protected override Conversion GetCollectionExpressionConversion(
Conversion elementConversion;
if (usesKeyValuePairs)
{
// PROTOTYPE: This change in behavior should only be enabled in C#14. Test both
// dictionaries and other collections of KeyValuePair<,> with earlier language version.
// PROTOTYPE: This change in behavior should only be enabled in C#14.
Debug.Assert(keyType.Type is { });
Debug.Assert(valueType.Type is { });
elementConversion = element switch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9388,12 +9388,12 @@ static void Main()
""";
var comp = CreateCompilation(source);
comp.VerifyEmitDiagnostics(
// (7,14): error CS7036: There is no argument given that corresponds to the required parameter 'value' of 'Dictionary<int, int>.Add(int, int)'
// (7,13): error CS9215: Collection expression type 'Dictionary<int, int>' must have an instance or extension method 'Add' that can be called with a single argument.
// d = [default];
Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "default").WithArguments("value", "System.Collections.Generic.Dictionary<int, int>.Add(int, int)").WithLocation(7, 14),
// (8,14): error CS7036: There is no argument given that corresponds to the required parameter 'value' of 'Dictionary<int, int>.Add(int, int)'
Diagnostic(ErrorCode.ERR_CollectionExpressionMissingAdd, "[default]").WithArguments("System.Collections.Generic.Dictionary<int, int>").WithLocation(7, 13),
// (8,13): error CS9215: Collection expression type 'Dictionary<int, int>' must have an instance or extension method 'Add' that can be called with a single argument.
// d = [new KeyValuePair<int, int>(1, 2)];
Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "new KeyValuePair<int, int>(1, 2)").WithArguments("value", "System.Collections.Generic.Dictionary<int, int>.Add(int, int)").WithLocation(8, 14),
Diagnostic(ErrorCode.ERR_CollectionExpressionMissingAdd, "[new KeyValuePair<int, int>(1, 2)]").WithArguments("System.Collections.Generic.Dictionary<int, int>").WithLocation(8, 13),
// (9,13): error CS9215: Collection expression type 'Dictionary<int, int>' must have an instance or extension method 'Add' that can be called with a single argument.
// d = [3:4];
Diagnostic(ErrorCode.ERR_CollectionExpressionMissingAdd, "[3:4]").WithArguments("System.Collections.Generic.Dictionary<int, int>").WithLocation(9, 13),
Expand Down

0 comments on commit 5da632a

Please sign in to comment.