Turning bool?.GetValueOrDefault() into `== true` ends an enclosing
null-conditional chain, so `c?.Flag.GetValueOrDefault()` became
`(c?.Flag == true)` of type bool instead of bool?. A following `?? false`
then fails to compile (CS0019), and a following `.ToString()` yields
"False" instead of null when c is null. Keep the call when its target is
part of a ?. chain.
A constrained GetAwaiter call on a type parameter that is not known to be
a value type wraps its receiver in LdObjIfRef so the reference is read
before any further arguments. ExpressionBuilder has no translation for
LdObjIfRef, so the operand was dropped. GetAwaiter takes no further
arguments, so the operand can be translated from the address, as
CallBuilder already does for call receivers.
When the branches of a conditional have different types, its type falls
back to the IL stack slot type, which is (U)IntPtr. IntroduceNativeIntTypeOnLocals
only retypes variables, so with native integers enabled the branches got
cast to IntPtr. Map (U)IntPtr to n(u)int the same way boxing does; pointer
types are unaffected.
When the extension method call cannot be written without type arguments
(another extension method with the same name and a different arity is
found first), the call falls back to the static form. For 'a?.M()' that
fallback produced 'Enumerable.Count(s?)', which is not valid C#. Writing
the type arguments excludes the extension methods of a different arity,
so for a null-conditional target the type arguments are tried before
giving up.