Slicing a span with a list pattern produces unnecessary bounds check
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
### Description
Given
```cs
static Span M(Span input) =>
input switch {
[_, ..var rest] => rest,
_ => input
};
```
Roslyn produces
```cs
static Span M(Span input)
{
int length = input.Length;
Span span;
if (length >= 1)
span = input.Slice(1, length - 1);
else
span = input;
return span;
}
```
Which is then compiled to
```asm
// coreclr trunk-20251010+e572463b5706b0509fe0c524d9d09893e7e252da
Program:M(System.Span`1[byte]):System.Span`1[byte] (FullOpts):
push rbp
mov rbp, rsp
test esi, esi
jg SHORT G_M16130_IG04
mov rax, rdi
mov edx, esi
jmp SHORT G_M16130_IG05
G_M16130_IG04: ;; offset=0x000F
lea edx, [rsi-0x01]
mov eax, edx
inc rax
mov ecx, esi
cmp rax, rcx
ja SHORT G_M16130_IG06
lea rax, bword ptr [rdi+0x01]
G_M16130_IG05: ;; offset=0x0022
pop rbp
ret
G_M16130_IG06: ;; offset=0x0024
call [System.ThrowHelper:ThrowArgumentOutOfRangeException()]
int3
```
Notably, rewriting it as
```cs
Span span;
if (input.Length >= 1)
span = input.Slice(1, input.Length - 1);
else
span = input;
return span;
```
results in the same output (also an issue with strings)
### Configuration
.NET runtime main branch commit e572463b5706b0509fe0c524d9d09893e7e252da
### Regression?
No
Contributor guide
Assessment
This issue has not been assessed yet.