| //@ compile-flags: -O -Zmerge-functions=disabled | |
| #![crate_type = "lib"] | |
| use std::collections::Bound; | |
| use std::ops::RangeBounds; | |
| #[no_mangle] | |
| pub fn raw_index(buf: &[u8]) -> Option<&[u8]> { | |
| // CHECK-LABEL: @raw_index( | |
| // CHECK-NOT: slice_index_fail | |
| // CHECK-NOT: br {{.*}} | |
| if buf.len() < 4 { None } else { Some(&buf[4..]) } | |
| } | |
| #[no_mangle] | |
| pub fn bounds_indexer(buf: &[u8]) -> Option<&[u8]> { | |
| // CHECK-LABEL: @bounds_indexer( | |
| // CHECK-NOT: slice_index_fail | |
| // CHECK-NOT: br {{.*}} | |
| // CHECK: ret | |
| if buf.len() < 4 { None } else { Some(&buf[(Bound::Included(4), Bound::Unbounded)]) } | |
| } | |
| #[no_mangle] | |
| pub fn bounds_indexer_with_range_bounds(buf: &[u8]) -> Option<&[u8]> { | |
| // CHECK-LABEL: @bounds_indexer_with_range_bounds( | |
| // CHECK-NOT: slice_index_fail | |
| // CHECK-NOT: br {{.*}} | |
| // CHECK: ret | |
| fn index(buf: &[u8], range: impl RangeBounds<usize>) -> &[u8] { | |
| &buf[(range.start_bound().map(|x| *x), range.end_bound().map(|x| *x))] | |
| } | |
| if buf.len() < 4 { None } else { Some(index(buf, 4..)) } | |
| } | |
| #[no_mangle] | |
| pub fn bounds_indexer_with_range_bounds_manual_map(buf: &[u8]) -> Option<&[u8]> { | |
| // CHECK-LABEL: @bounds_indexer_with_range_bounds_manual_map( | |
| // CHECK-NOT: slice_index_fail | |
| // CHECK-NOT: br {{.*}} | |
| // CHECK: ret | |
| fn index(buf: &[u8], range: impl RangeBounds<usize>) -> &[u8] { | |
| &buf[( | |
| match range.start_bound() { | |
| Bound::Included(&i) => Bound::Included(i), | |
| Bound::Excluded(&i) => Bound::Excluded(i), | |
| Bound::Unbounded => Bound::Unbounded, | |
| }, | |
| match range.end_bound() { | |
| Bound::Included(&i) => Bound::Included(i), | |
| Bound::Excluded(&i) => Bound::Excluded(i), | |
| Bound::Unbounded => Bound::Unbounded, | |
| }, | |
| )] | |
| } | |
| if buf.len() < 4 { None } else { Some(index(buf, 4..)) } | |
| } | |
| #[no_mangle] | |
| pub fn bounds_indexer_with_range_bounds_manually_mapped(buf: &[u8]) -> Option<&[u8]> { | |
| // CHECK-LABEL: @bounds_indexer_with_range_bounds_manually_mapped( | |
| // CHECK-NOT: slice_index_fail | |
| // CHECK-NOT: br {{.*}} | |
| // CHECK: ret | |
| fn index(buf: &[u8], range: impl RangeBounds<usize>) -> &[u8] { | |
| &buf[match range.start_bound() { | |
| Bound::Included(&i) => i, | |
| Bound::Excluded(i) => i.checked_add(1).expect("overflow"), | |
| Bound::Unbounded => 0, | |
| }..match range.end_bound() { | |
| Bound::Included(&i) => i, | |
| Bound::Excluded(i) => i.checked_sub(1).expect("overflow"), | |
| Bound::Unbounded => buf.len(), | |
| }] | |
| } | |
| if buf.len() < 4 { None } else { Some(index(buf, 4..)) } | |
| } |