Skip to content

Commit 9605f94

Browse files
authored
Rollup merge of #76142 - CDirkx:const-ip, r=ecstatic-morse
Make all methods of `std::net::Ipv4Addr` const Make the following methods of `std::net::Ipv4Addr` unstable const under the `const_ipv4` feature: - `octets` - `is_loopback` - `is_private` - `is_link_local` - `is_global` (unstable) - `is_shared` (unstable) - `is_ietf_protocol_assignment` (unstable) - `is_benchmarking` (unstable) - `is_reserved` (unstable) - `is_multicast` - `is_broadcast` - `is_documentation` - `to_ipv6_compatible` - `to_ipv6_mapped` This would make all methods of `Ipv6Addr` const. Of these methods, `is_global`, `is_broadcast`, `to_ipv6_compatible`, and `to_ipv6_mapped` require a change in implementation. Part of #76205
2 parents 10aa3d3 + 0c77257 commit 9605f94

File tree

3 files changed

+97
-18
lines changed

3 files changed

+97
-18
lines changed

library/std/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@
240240
#![feature(const_fn_transmute)]
241241
#![feature(const_ipv6)]
242242
#![feature(const_raw_ptr_deref)]
243+
#![feature(const_ipv4)]
243244
#![feature(container_error_extra)]
244245
#![feature(core_intrinsics)]
245246
#![feature(custom_test_frameworks)]

library/std/src/net/ip.rs

+38-18
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,9 @@ impl Ipv4Addr {
365365
/// let addr = Ipv4Addr::new(127, 0, 0, 1);
366366
/// assert_eq!(addr.octets(), [127, 0, 0, 1]);
367367
/// ```
368+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
368369
#[stable(feature = "rust1", since = "1.0.0")]
369-
pub fn octets(&self) -> [u8; 4] {
370+
pub const fn octets(&self) -> [u8; 4] {
370371
// This returns the order we want because s_addr is stored in big-endian.
371372
self.inner.s_addr.to_ne_bytes()
372373
}
@@ -408,8 +409,9 @@ impl Ipv4Addr {
408409
/// assert_eq!(Ipv4Addr::new(127, 0, 0, 1).is_loopback(), true);
409410
/// assert_eq!(Ipv4Addr::new(45, 22, 13, 197).is_loopback(), false);
410411
/// ```
412+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
411413
#[stable(since = "1.7.0", feature = "ip_17")]
412-
pub fn is_loopback(&self) -> bool {
414+
pub const fn is_loopback(&self) -> bool {
413415
self.octets()[0] == 127
414416
}
415417

@@ -437,8 +439,9 @@ impl Ipv4Addr {
437439
/// assert_eq!(Ipv4Addr::new(192, 168, 0, 2).is_private(), true);
438440
/// assert_eq!(Ipv4Addr::new(192, 169, 0, 2).is_private(), false);
439441
/// ```
442+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
440443
#[stable(since = "1.7.0", feature = "ip_17")]
441-
pub fn is_private(&self) -> bool {
444+
pub const fn is_private(&self) -> bool {
442445
match self.octets() {
443446
[10, ..] => true,
444447
[172, b, ..] if b >= 16 && b <= 31 => true,
@@ -463,8 +466,9 @@ impl Ipv4Addr {
463466
/// assert_eq!(Ipv4Addr::new(169, 254, 10, 65).is_link_local(), true);
464467
/// assert_eq!(Ipv4Addr::new(16, 89, 10, 65).is_link_local(), false);
465468
/// ```
469+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
466470
#[stable(since = "1.7.0", feature = "ip_17")]
467-
pub fn is_link_local(&self) -> bool {
471+
pub const fn is_link_local(&self) -> bool {
468472
match self.octets() {
469473
[169, 254, ..] => true,
470474
_ => false,
@@ -542,10 +546,13 @@ impl Ipv4Addr {
542546
/// assert_eq!(Ipv4Addr::new(1, 1, 1, 1).is_global(), true);
543547
/// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
544548
/// ```
545-
pub fn is_global(&self) -> bool {
549+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
550+
pub const fn is_global(&self) -> bool {
546551
// check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
547552
// globally routable addresses in the 192.0.0.0/24 range.
548-
if u32::from(*self) == 0xc0000009 || u32::from(*self) == 0xc000000a {
553+
if u32::from_be_bytes(self.octets()) == 0xc0000009
554+
|| u32::from_be_bytes(self.octets()) == 0xc000000a
555+
{
549556
return true;
550557
}
551558
!self.is_private()
@@ -577,7 +584,8 @@ impl Ipv4Addr {
577584
/// assert_eq!(Ipv4Addr::new(100, 127, 255, 255).is_shared(), true);
578585
/// assert_eq!(Ipv4Addr::new(100, 128, 0, 0).is_shared(), false);
579586
/// ```
580-
pub fn is_shared(&self) -> bool {
587+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
588+
pub const fn is_shared(&self) -> bool {
581589
self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000)
582590
}
583591

@@ -609,7 +617,8 @@ impl Ipv4Addr {
609617
/// assert_eq!(Ipv4Addr::new(192, 0, 1, 0).is_ietf_protocol_assignment(), false);
610618
/// assert_eq!(Ipv4Addr::new(191, 255, 255, 255).is_ietf_protocol_assignment(), false);
611619
/// ```
612-
pub fn is_ietf_protocol_assignment(&self) -> bool {
620+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
621+
pub const fn is_ietf_protocol_assignment(&self) -> bool {
613622
self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0
614623
}
615624

@@ -632,7 +641,8 @@ impl Ipv4Addr {
632641
/// assert_eq!(Ipv4Addr::new(198, 19, 255, 255).is_benchmarking(), true);
633642
/// assert_eq!(Ipv4Addr::new(198, 20, 0, 0).is_benchmarking(), false);
634643
/// ```
635-
pub fn is_benchmarking(&self) -> bool {
644+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
645+
pub const fn is_benchmarking(&self) -> bool {
636646
self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18
637647
}
638648

@@ -664,7 +674,8 @@ impl Ipv4Addr {
664674
/// // The broadcast address is not considered as reserved for future use by this implementation
665675
/// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_reserved(), false);
666676
/// ```
667-
pub fn is_reserved(&self) -> bool {
677+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
678+
pub const fn is_reserved(&self) -> bool {
668679
self.octets()[0] & 240 == 240 && !self.is_broadcast()
669680
}
670681

@@ -685,8 +696,9 @@ impl Ipv4Addr {
685696
/// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_multicast(), true);
686697
/// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_multicast(), false);
687698
/// ```
699+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
688700
#[stable(since = "1.7.0", feature = "ip_17")]
689-
pub fn is_multicast(&self) -> bool {
701+
pub const fn is_multicast(&self) -> bool {
690702
self.octets()[0] >= 224 && self.octets()[0] <= 239
691703
}
692704

@@ -705,9 +717,10 @@ impl Ipv4Addr {
705717
/// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_broadcast(), true);
706718
/// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_broadcast(), false);
707719
/// ```
720+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
708721
#[stable(since = "1.7.0", feature = "ip_17")]
709-
pub fn is_broadcast(&self) -> bool {
710-
self == &Self::BROADCAST
722+
pub const fn is_broadcast(&self) -> bool {
723+
u32::from_be_bytes(self.octets()) == u32::from_be_bytes(Self::BROADCAST.octets())
711724
}
712725

713726
/// Returns [`true`] if this address is in a range designated for documentation.
@@ -731,8 +744,9 @@ impl Ipv4Addr {
731744
/// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_documentation(), true);
732745
/// assert_eq!(Ipv4Addr::new(193, 34, 17, 19).is_documentation(), false);
733746
/// ```
747+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
734748
#[stable(since = "1.7.0", feature = "ip_17")]
735-
pub fn is_documentation(&self) -> bool {
749+
pub const fn is_documentation(&self) -> bool {
736750
match self.octets() {
737751
[192, 0, 2, _] => true,
738752
[198, 51, 100, _] => true,
@@ -760,10 +774,13 @@ impl Ipv4Addr {
760774
/// Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 767)
761775
/// );
762776
/// ```
777+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
763778
#[stable(feature = "rust1", since = "1.0.0")]
764-
pub fn to_ipv6_compatible(&self) -> Ipv6Addr {
779+
pub const fn to_ipv6_compatible(&self) -> Ipv6Addr {
765780
let [a, b, c, d] = self.octets();
766-
Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d])
781+
Ipv6Addr {
782+
inner: c::in6_addr { s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d] },
783+
}
767784
}
768785

769786
/// Converts this address to an IPv4-mapped [`IPv6` address].
@@ -780,10 +797,13 @@ impl Ipv4Addr {
780797
/// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).to_ipv6_mapped(),
781798
/// Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 49152, 767));
782799
/// ```
800+
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
783801
#[stable(feature = "rust1", since = "1.0.0")]
784-
pub fn to_ipv6_mapped(&self) -> Ipv6Addr {
802+
pub const fn to_ipv6_mapped(&self) -> Ipv6Addr {
785803
let [a, b, c, d] = self.octets();
786-
Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d])
804+
Ipv6Addr {
805+
inner: c::in6_addr { s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d] },
806+
}
787807
}
788808
}
789809

src/test/ui/consts/std/net/ipv4.rs

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// run-pass
2+
3+
#![feature(ip)]
4+
#![feature(const_ipv4)]
5+
6+
use std::net::{Ipv4Addr, Ipv6Addr};
7+
8+
fn main() {
9+
const IP_ADDRESS: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
10+
assert_eq!(IP_ADDRESS, Ipv4Addr::LOCALHOST);
11+
12+
const OCTETS: [u8; 4] = IP_ADDRESS.octets();
13+
assert_eq!(OCTETS, [127, 0, 0, 1]);
14+
15+
const IS_UNSPECIFIED : bool = IP_ADDRESS.is_unspecified();
16+
assert!(!IS_UNSPECIFIED);
17+
18+
const IS_LOOPBACK : bool = IP_ADDRESS.is_loopback();
19+
assert!(IS_LOOPBACK);
20+
21+
const IS_PRIVATE : bool = IP_ADDRESS.is_private();
22+
assert!(!IS_PRIVATE);
23+
24+
const IS_LINK_LOCAL : bool = IP_ADDRESS.is_link_local();
25+
assert!(!IS_LINK_LOCAL);
26+
27+
const IS_GLOBAL : bool = IP_ADDRESS.is_global();
28+
assert!(!IS_GLOBAL);
29+
30+
const IS_SHARED : bool = IP_ADDRESS.is_shared();
31+
assert!(!IS_SHARED);
32+
33+
const IS_IETF_PROTOCOL_ASSIGNMENT : bool = IP_ADDRESS.is_ietf_protocol_assignment();
34+
assert!(!IS_IETF_PROTOCOL_ASSIGNMENT);
35+
36+
const IS_BENCHMARKING : bool = IP_ADDRESS.is_benchmarking();
37+
assert!(!IS_BENCHMARKING);
38+
39+
const IS_RESERVED : bool = IP_ADDRESS.is_reserved();
40+
assert!(!IS_RESERVED);
41+
42+
const IS_MULTICAST : bool = IP_ADDRESS.is_multicast();
43+
assert!(!IS_MULTICAST);
44+
45+
const IS_BROADCAST : bool = IP_ADDRESS.is_broadcast();
46+
assert!(!IS_BROADCAST);
47+
48+
const IS_DOCUMENTATION : bool = IP_ADDRESS.is_documentation();
49+
assert!(!IS_DOCUMENTATION);
50+
51+
const IP_V6_COMPATIBLE : Ipv6Addr = IP_ADDRESS.to_ipv6_compatible();
52+
assert_eq!(IP_V6_COMPATIBLE,
53+
Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 1]));
54+
55+
const IP_V6_MAPPED : Ipv6Addr = IP_ADDRESS.to_ipv6_mapped();
56+
assert_eq!(IP_V6_MAPPED,
57+
Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1]));
58+
}

0 commit comments

Comments
 (0)