With every optional slot nullable, the null-object pattern is dead. Generated
non-nullable getters return the backing field directly, which surfaced a last
tier of slots the decompiler legitimately leaves empty (omitted range operands,
an implicitly-typed array creation, unnamed parameters, an unbound generic
argument, and others) and flips them to nullable too. The machinery is then
removed entirely: the per-node null classes, the .Null statics and
VisitNullNode, AstNode.IsNull, the role null object, and Identifier.Null.
AcceptVisitor becomes unconditionally generated, and consumers move from
.IsNull to is null and from unconditional visits to ?.AcceptVisitor.
Assisted-by: Claude:claude-opus-4-8:Claude Code
Turn on #nullable enable across the AST transform pipeline, ahead of
annotating the slot properties themselves. TransformContext now exposes the
nullable CurrentMember/CurrentTypeDefinition/CurrentModule contract already
declared by ITypeResolveContext, and the generated pattern-to-node conversion
returns a non-null node so patterns can be used in collection initializers
without warnings. No IL changes.
Assisted-by: Claude:claude-opus-4-8:Claude Code
* ensure constant expressions of small integer type have the correct type
* add checked/unchecked annotations for casts, so that we generate the appropriate checked/unchecked blocks
* avoid moving label statements into checked blocks