about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-09-17 06:27:09 +0000
committerbors <bors@rust-lang.org>2023-09-17 06:27:09 +0000
commit3ecc563628d0ca62c3b6983c1cd05c4d4a0002b2 (patch)
treedc1eaad94f56431b930a097f7e7a270cdddefaf7
parenta09c1f85f1bc5be9a85e1395e7482caff91260cc (diff)
parent8184c9c50d227172317debbd9793b26f17ed9fea (diff)
downloadrust-3ecc563628d0ca62c3b6983c1cd05c4d4a0002b2.tar.gz
rust-3ecc563628d0ca62c3b6983c1cd05c4d4a0002b2.zip
Auto merge of #113748 - clarfonthey:ip-step, r=dtolnay
impl Step for IP addresses

ACP: rust-lang/libs-team#235

Note: since this is insta-stable, it requires an FCP.

Separating out from the bit operations PR since it feels logically disjoint, and so their FCPs can be separate.
-rw-r--r--library/core/src/iter/range.rs67
-rw-r--r--tests/ui/range/range-1.stderr2
2 files changed, 67 insertions, 2 deletions
diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs
index 391e03636ab..0e03d0c2d4e 100644
--- a/library/core/src/iter/range.rs
+++ b/library/core/src/iter/range.rs
@@ -1,6 +1,7 @@
 use crate::ascii::Char as AsciiChar;
 use crate::convert::TryFrom;
 use crate::mem;
+use crate::net::{Ipv4Addr, Ipv6Addr};
 use crate::num::NonZeroUsize;
 use crate::ops::{self, Try};
 
@@ -15,7 +16,7 @@ macro_rules! unsafe_impl_trusted_step {
         unsafe impl TrustedStep for $type {}
     )*};
 }
-unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize];
+unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize Ipv4Addr Ipv6Addr];
 
 /// Objects that have a notion of *successor* and *predecessor* operations.
 ///
@@ -527,6 +528,70 @@ impl Step for AsciiChar {
     }
 }
 
+#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
+impl Step for Ipv4Addr {
+    #[inline]
+    fn steps_between(&start: &Ipv4Addr, &end: &Ipv4Addr) -> Option<usize> {
+        u32::steps_between(&start.to_bits(), &end.to_bits())
+    }
+
+    #[inline]
+    fn forward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
+        u32::forward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
+    }
+
+    #[inline]
+    fn backward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
+        u32::backward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
+    }
+
+    #[inline]
+    unsafe fn forward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
+        // SAFETY: Since u32 and Ipv4Addr are losslessly convertible,
+        //   this is as safe as the u32 version.
+        Ipv4Addr::from_bits(unsafe { u32::forward_unchecked(start.to_bits(), count) })
+    }
+
+    #[inline]
+    unsafe fn backward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
+        // SAFETY: Since u32 and Ipv4Addr are losslessly convertible,
+        //   this is as safe as the u32 version.
+        Ipv4Addr::from_bits(unsafe { u32::backward_unchecked(start.to_bits(), count) })
+    }
+}
+
+#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
+impl Step for Ipv6Addr {
+    #[inline]
+    fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> Option<usize> {
+        u128::steps_between(&start.to_bits(), &end.to_bits())
+    }
+
+    #[inline]
+    fn forward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
+        u128::forward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
+    }
+
+    #[inline]
+    fn backward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
+        u128::backward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
+    }
+
+    #[inline]
+    unsafe fn forward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
+        // SAFETY: Since u128 and Ipv6Addr are losslessly convertible,
+        //   this is as safe as the u128 version.
+        Ipv6Addr::from_bits(unsafe { u128::forward_unchecked(start.to_bits(), count) })
+    }
+
+    #[inline]
+    unsafe fn backward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
+        // SAFETY: Since u128 and Ipv6Addr are losslessly convertible,
+        //   this is as safe as the u128 version.
+        Ipv6Addr::from_bits(unsafe { u128::backward_unchecked(start.to_bits(), count) })
+    }
+}
+
 macro_rules! range_exact_iter_impl {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr
index ecfc56961ee..96c1ffb2f7e 100644
--- a/tests/ui/range/range-1.stderr
+++ b/tests/ui/range/range-1.stderr
@@ -19,7 +19,7 @@ LL |     for i in false..true {}
              i64
              i128
              usize
-           and 6 others
+           and 8 others
    = note: required for `std::ops::Range<bool>` to implement `Iterator`
    = note: required for `std::ops::Range<bool>` to implement `IntoIterator`