Skip to content

Commit 0039763

Browse files
author
Julien Couvreur
authored
Merge features/extensions into main branch (#79860)
This brings the implementation of the new metadata design
2 parents b4860b0 + 50d8228 commit 0039763

File tree

139 files changed

+28985
-9895
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

139 files changed

+28985
-9895
lines changed

src/Compilers/CSharp/Portable/Binder/Semantics/Operators/UnaryOperatorOverloadResolution.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -261,17 +261,29 @@ public bool Equals(MethodSymbol? x, MethodSymbol? y)
261261
return false;
262262
}
263263

264-
var xGroupingKey = new SourceMemberContainerTypeSymbol.ExtensionGroupingKey(x.OriginalDefinition.ContainingType);
265-
var yGroupingKey = new SourceMemberContainerTypeSymbol.ExtensionGroupingKey(y.OriginalDefinition.ContainingType);
264+
var xExtension = x.OriginalDefinition.ContainingType;
265+
var xGroupingKey = ((SourceNamedTypeSymbol)xExtension).ExtensionGroupingName;
266+
var yExtension = y.OriginalDefinition.ContainingType;
267+
var yGroupingKey = ((SourceNamedTypeSymbol)yExtension).ExtensionGroupingName;
266268

267269
if (!xGroupingKey.Equals(yGroupingKey))
268270
{
269271
return false;
270272
}
271273

272274
return SourceMemberContainerTypeSymbol.DoOperatorsPair(
273-
x.OriginalDefinition.AsMember(xGroupingKey.NormalizedExtension),
274-
y.OriginalDefinition.AsMember(yGroupingKey.NormalizedExtension));
275+
x.OriginalDefinition.AsMember(Normalize(xExtension)),
276+
y.OriginalDefinition.AsMember(Normalize(yExtension)));
277+
}
278+
279+
private static NamedTypeSymbol Normalize(NamedTypeSymbol extension)
280+
{
281+
if (extension.Arity != 0)
282+
{
283+
extension = extension.Construct(IndexedTypeParameterSymbol.Take(extension.Arity));
284+
}
285+
286+
return extension;
275287
}
276288

277289
public int GetHashCode(MethodSymbol op)
@@ -280,10 +292,11 @@ public int GetHashCode(MethodSymbol op)
280292

281293
int result = typeComparer.GetHashCode(op.OriginalDefinition.ContainingType.ContainingType);
282294

283-
var groupingKey = new SourceMemberContainerTypeSymbol.ExtensionGroupingKey(op.OriginalDefinition.ContainingType);
295+
var extension = op.OriginalDefinition.ContainingType;
296+
var groupingKey = ((SourceNamedTypeSymbol)extension).ExtensionGroupingName;
284297
result = Hash.Combine(result, groupingKey.GetHashCode());
285298

286-
foreach (var parameter in op.OriginalDefinition.AsMember(groupingKey.NormalizedExtension).Parameters)
299+
foreach (var parameter in op.OriginalDefinition.AsMember(Normalize(extension)).Parameters)
287300
{
288301
result = Hash.Combine(result, typeComparer.GetHashCode(parameter.Type));
289302
}

src/Compilers/CSharp/Portable/CSharpResources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8224,4 +8224,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
82248224
<data name="ERR_MemberNameSameAsExtendedType" xml:space="preserve">
82258225
<value>'{0}': extension member names cannot be the same as their extended type</value>
82268226
</data>
8227+
<data name="ERR_ExtensionBlockCollision" xml:space="preserve">
8228+
<value>This extension block collides with another extension block. They result in conflicting content-based type names in metadata, so must be in separate enclosing static classes.</value>
8229+
</data>
82278230
</root>

src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -720,28 +720,39 @@ private void EmitArgument(BoundExpression argument, RefKind refKind)
720720
EmitExpression(argument, true);
721721
break;
722722

723-
case RefKind.In:
724-
var temp = EmitAddress(argument, AddressKind.ReadOnly);
725-
AddExpressionTemp(temp);
726-
break;
727-
728723
default:
729-
Debug.Assert(refKind is RefKind.Ref or RefKind.Out or RefKindExtensions.StrictIn);
730-
// NOTE: passing "ReadOnlyStrict" here.
731-
// we should not get an address of a copy if at all possible
732-
var unexpectedTemp = EmitAddress(argument, refKind == RefKindExtensions.StrictIn ? AddressKind.ReadOnlyStrict : AddressKind.Writeable);
733-
if (unexpectedTemp != null)
724+
Debug.Assert(refKind is RefKind.In or RefKind.Ref or RefKind.Out or RefKindExtensions.StrictIn);
725+
var temp = EmitAddress(argument, GetArgumentAddressKind(refKind));
726+
if (temp != null)
734727
{
735728
// interestingly enough "ref dynamic" sometimes is passed via a clone
736729
// receiver of a ref field can be cloned too
737-
Debug.Assert(argument.Type.IsDynamic() || argument is BoundFieldAccess { FieldSymbol.RefKind: not RefKind.None }, "passing args byref should not clone them into temps");
738-
AddExpressionTemp(unexpectedTemp);
730+
Debug.Assert(refKind is RefKind.In || argument.Type.IsDynamic() || argument is BoundFieldAccess { FieldSymbol.RefKind: not RefKind.None }, "passing args byref should not clone them into temps");
731+
AddExpressionTemp(temp);
739732
}
740733

741734
break;
742735
}
743736
}
744737

738+
internal static AddressKind GetArgumentAddressKind(RefKind refKind)
739+
{
740+
switch (refKind)
741+
{
742+
case RefKind.None:
743+
throw ExceptionUtilities.UnexpectedValue(refKind);
744+
745+
case RefKind.In:
746+
return AddressKind.ReadOnly;
747+
748+
default:
749+
Debug.Assert(refKind is RefKind.Ref or RefKind.Out or RefKindExtensions.StrictIn);
750+
// NOTE: returning "ReadOnlyStrict" here.
751+
// we should not get an address of a copy if at all possible
752+
return refKind == RefKindExtensions.StrictIn ? AddressKind.ReadOnlyStrict : AddressKind.Writeable;
753+
}
754+
}
755+
745756
private void EmitAddressOfExpression(BoundAddressOfOperator expression, bool used)
746757
{
747758
// NOTE: passing "ReadOnlyStrict" here.

0 commit comments

Comments
 (0)