Skip to content

Commit b665721

Browse files
Remove sorting requirement for interface lists (#60541)
Fixes #60454.
1 parent 704f023 commit b665721

File tree

3 files changed

+14
-50
lines changed

3 files changed

+14
-50
lines changed

docs/design/specs/Ecma-335-Augments.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This is a list of additions and edits to be made in ECMA-335 specifications. It
77
- [Signatures](#signatures)
88
- [Heap sizes](#heap-sizes)
99
- [Metadata merging](#metadata-merging)
10+
- [Metadata logical format](#metadata-logical-format)
1011
- [Module Initializer](#module-initializer)
1112
- [Default Interface Methods](#default-interface-methods)
1213
- [Static Interface Methods](#static-interface-methods)
@@ -362,6 +363,14 @@ This text should be deleted, and the _metadata merging_ entry should be removed
362363
> * ~~If there are duplicates and two or more have an accessibility other than
363364
> **compilercontrolled**, an error has occurred.~~
364365
366+
## Metadata logical format
367+
368+
The requirement to sort InterfaceImpl table using the Interface column as a secondary key in § II.22 _Metadata logical format: tables_ is a spec bug. The interface declaration order affects resolution and a requirement to sort it would make it impossible to emit certain sequences of interfaces (e.g. not possible to have an interface list I1, I2, while also having interface list I2, I1 elsewhere in the module).
369+
370+
The text should be deleted:
371+
372+
> Furthermore, ~~the InterfaceImpl table is sorted using the Interface column as a secondary key, and~~ the GenericParam table is sorted using the Number column as a secondary key.
373+
365374
## Module Initializer
366375

367376
All modules may have a module initializer. A module initializer is defined as the type initializer (§ II.10.5.3) of the `<Module>` type (§ II.10.8).

src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/MetadataBuilder.Tables.cs

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,7 +1434,7 @@ internal void ValidateOrder()
14341434
// GenericParam Owner, Number No**
14351435
// GenericParamConstraint Owner No**
14361436
// ImplMap MemberForwarded No*
1437-
// InterfaceImpl Class, Interface No**
1437+
// InterfaceImpl Class No**
14381438
// MethodImpl Class No*
14391439
// MethodSemantics Association Yes
14401440
// NestedClass NestedClass No*
@@ -1551,27 +1551,12 @@ private void ValidateImplMapTable()
15511551

15521552
private void ValidateInterfaceImplTable()
15531553
{
1554-
if (_interfaceImplTable.Count == 0)
1554+
for (int i = 1; i < _interfaceImplTable.Count; i++)
15551555
{
1556-
return;
1557-
}
1558-
1559-
InterfaceImplRow current, previous = _interfaceImplTable[0];
1560-
for (int i = 1; i < _interfaceImplTable.Count; i++, previous = current)
1561-
{
1562-
current = _interfaceImplTable[i];
1563-
1564-
if (current.Class > previous.Class)
1556+
if (_interfaceImplTable[i - 1].Class > _interfaceImplTable[i].Class)
15651557
{
1566-
continue;
1558+
Throw.InvalidOperation_TableNotSorted(TableIndex.InterfaceImpl);
15671559
}
1568-
1569-
if (previous.Class == current.Class && current.Interface > previous.Interface)
1570-
{
1571-
continue;
1572-
}
1573-
1574-
Throw.InvalidOperation_TableNotSorted(TableIndex.InterfaceImpl);
15751560
}
15761561
}
15771562

src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/MetadataBuilderTests.cs

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -803,40 +803,10 @@ public void ValidateInterfaceImplTable()
803803
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeDefinitionHandle(1));
804804
Assert.Throws<InvalidOperationException>(() => builder.ValidateOrder());
805805

806-
builder = new MetadataBuilder();
807-
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeDefinitionHandle(1));
808-
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeDefinitionHandle(1));
809-
Assert.Throws<InvalidOperationException>(() => builder.ValidateOrder());
810-
811806
builder = new MetadataBuilder();
812807
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeDefinitionHandle(2));
813808
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeDefinitionHandle(1));
814-
Assert.Throws<InvalidOperationException>(() => builder.ValidateOrder());
815-
816-
builder = new MetadataBuilder();
817-
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeReferenceHandle(2));
818-
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeReferenceHandle(1));
819-
Assert.Throws<InvalidOperationException>(() => builder.ValidateOrder());
820-
821-
builder = new MetadataBuilder();
822-
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeSpecificationHandle(2));
823-
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeSpecificationHandle(1));
824-
Assert.Throws<InvalidOperationException>(() => builder.ValidateOrder());
825-
826-
builder = new MetadataBuilder();
827-
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeReferenceHandle(1));
828-
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeDefinitionHandle(1));
829-
Assert.Throws<InvalidOperationException>(() => builder.ValidateOrder());
830-
831-
builder = new MetadataBuilder();
832-
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeSpecificationHandle(1));
833-
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeReferenceHandle(1));
834-
Assert.Throws<InvalidOperationException>(() => builder.ValidateOrder());
835-
836-
builder = new MetadataBuilder();
837-
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeSpecificationHandle(1));
838-
builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeDefinitionHandle(1));
839-
Assert.Throws<InvalidOperationException>(() => builder.ValidateOrder());
809+
builder.ValidateOrder(); // ok
840810
}
841811

842812
[Fact]

0 commit comments

Comments
 (0)