C# only accepts System.ValueTuple as a tuple when it is a struct, so a class of
that name is an unrelated type and rendering it with tuple syntax describes it
as something it is not. It also made a tuple appear to contain itself, which no
struct can, and the deconstruction transform then registered the same variable
as a node of its tuple tree twice and threw ArgumentException, failing the whole
method instead of leaving the statements alone.
The check has accepted classes since tuples were added to the type system,
alongside a name comparison against "ValueType" that was corrected later.
Assisted-by: Claude:claude-opus-5[1m]:Claude Code
GetTupleElementTypes returns a default ImmutableArray when the type is
not tuple-compatible, so reading Length threw NullReferenceException
instead of taking the documented return-null path.
Assisted-by: Claude:claude-fable-5:Claude Code
This can happen if an application is compiled for .NET 4.6.2 and references
System.ValueTuple.dll; but ILSpy loads the latest mscorlib (e.g. .NET 4.7)
which also contains struct System.ValueTuple.
While support for multi-module assemblies isn't fully working yet; it is clear at this point that we want
to treat each module in a multi-module assembly separately for the purposes of the type system.
This was the last place where the public API of the resolved TS was referencing the unresolved TS.
We could now implement the resolved TS directly using SRM, and remove the whole unresolved TS layer.
* Use tuple literals instead of calling 'new ValueTuple<..>' constructor
* Where available, use element names for field access
* Make CallBuilder aware of tuple-name/dynamic type erasure, to avoid introducing casts when the types differ only in the tuple element names.
* Make CallBuilder provide a ResolveResult with the correct C# return type for the resulting expression.
Previously we were using the type-erased return type from the IL.
* Fix a bug that caused us to introduce returning casts when accessing an indexer.