You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
Since #592, ConsumeContextConverterGenerator orders switch arms by a specificity rank: the number of base classes plus all interfaces (GetSpecificity, L144–L149). The rank relies on a type having strictly more supertypes than any of its supertypes.
That does not hold for object versus an interface with no base interfaces. An interface converts to object, but object is not in its BaseType chain or in AllInterfaces, so both get rank 0. Ties keep discovery order, so an object arm discovered first is emitted before the interface arm and subsumes it (CS8510).
This is not reachable today: object as a message type currently produces global::object, which fails earlier with a syntax error (#593). It becomes a real build break as soon as #593 is fixed, so the two are best fixed together.
Verified with CSharpGeneratorDriver against dev at 9179885 with a temporary local fix for #593 applied: the arms come out in that order and the second one is reported as CS8510. Without that fix the same order is emitted, but the global::object syntax error is reported first.
Expected behavior
An object arm is always emitted last, after every other type.
Every type other than object converts to object, so the rank can count it for interfaces too. One way:
staticintGetSpecificity(ITypeSymbolsymbol){// Interfaces convert to object although it is not among their base typesvarcount=symbol.AllInterfaces.Length+(symbol.TypeKind==TypeKind.Interface?1:0);for(varbaseType=symbol.BaseType;baseType!=null;baseType=baseType.BaseType)count++;returncount;}
The strict ordering still holds: a class implementing I counts object, I and everything I counts, so it stays above I; a derived interface stays above its base interface; and object is the only type left at rank 0.
Checked locally with this change plus the #593 fix applied: the scenario above compiles with the IFoo arm emitted first, and the existing ConsumeContextConverterGeneratorTests still pass.
Additional context
Found while working on #589 / #592. Low priority on its own since object message types are unusual, but it should be covered by a test when #593 is fixed, otherwise that fix trades one build error for another in this scenario.
Describe the bug
Since #592,
ConsumeContextConverterGeneratororders switch arms by a specificity rank: the number of base classes plus all interfaces (GetSpecificity, L144–L149). The rank relies on a type having strictly more supertypes than any of its supertypes.That does not hold for
objectversus an interface with no base interfaces. An interface converts toobject, butobjectis not in itsBaseTypechain or inAllInterfaces, so both get rank 0. Ties keep discovery order, so anobjectarm discovered first is emitted before the interface arm and subsumes it (CS8510).This is not reachable today:
objectas a message type currently producesglobal::object, which fails earlier with a syntax error (#593). It becomes a real build break as soon as #593 is fixed, so the two are best fixed together.To Reproduce
UseSpecialTypes).objectas a message type before an interface that has no base interfaces:Verified with
CSharpGeneratorDriveragainstdevat 9179885 with a temporary local fix for #593 applied: the arms come out in that order and the second one is reported asCS8510. Without that fix the same order is emitted, but theglobal::objectsyntax error is reported first.Expected behavior
An
objectarm is always emitted last, after every other type.Every type other than
objectconverts toobject, so the rank can count it for interfaces too. One way:The strict ordering still holds: a class implementing
Icountsobject,Iand everythingIcounts, so it stays aboveI; a derived interface stays above its base interface; andobjectis the only type left at rank 0.Checked locally with this change plus the #593 fix applied: the scenario above compiles with the
IFooarm emitted first, and the existingConsumeContextConverterGeneratorTestsstill pass.Additional context
Found while working on #589 / #592. Low priority on its own since
objectmessage types are unusual, but it should be covered by a test when #593 is fixed, otherwise that fix trades one build error for another in this scenario.