Better codegen for conditional-access + pattern checks.
#69,411 opened on Aug 5, 2023
Repository metrics
- Stars
- (20,414 stars)
- PR merge metrics
- (Avg merge 6d 17h) (256 merged PRs in 30d)
Description
Given code like the following:
static void Main(string[] args)
{
if (args?.Length is 1)
Console.WriteLine(true);
}
The compiler currently compiles that similarly to the following:
int? __t1 = __argsTemp?.Length;
if (__t1.HasValue && __t1.GetValueOrDefault() == 1) ...
While correct, this appears to be unnecessarily expensive. Specifically, because the pattern itself does not have null in its acceptance-set, there's no need to actually produce and instantiate a nullable-int on the stack just to test that instead. Rather, the above would be better compiled to something similar to:
if (__argsTemp != null && __argsTemp.Length is 1)
In other words, once the null check is performed, if it is null, then the value of args?.Length would be known to be null, which could never match 1, so no further checks are necessary. However, if the null check is performed and the value is not null, then it is known that it is safe to access members of it directly. This avoids unnecessary nullable allocations on the stack in either case.
Note: this could also be done for operators like == and != on primitive types, when the comparands are constants.