Skip to content

Commit

Permalink
Make all remaining methods of std::net::Ipv4Addr const
Browse files Browse the repository at this point in the history
Makes the following methods of `std::net::Ipv4Addr` unstable const under the `const_ipv4` feature:
 - `is_global`
 - `is_reserved`
 - `is_broadcast`
 - `to_ipv6_compatible`
 - `to_ipv6_mapped`

This results in all methods of `Ipv4Addr` being const.

Also adds tests for these methods in a const context.
  • Loading branch information
CDirkx committed Sep 1, 2020
1 parent fb64e6d commit 0c77257
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 10 deletions.
29 changes: 20 additions & 9 deletions library/std/src/net/ip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,10 +542,13 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(1, 1, 1, 1).is_global(), true);
/// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
/// ```
pub fn is_global(&self) -> bool {
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
pub const fn is_global(&self) -> bool {
// check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
// globally routable addresses in the 192.0.0.0/24 range.
if u32::from(*self) == 0xc0000009 || u32::from(*self) == 0xc000000a {
if u32::from_be_bytes(self.octets()) == 0xc0000009
|| u32::from_be_bytes(self.octets()) == 0xc000000a
{
return true;
}
!self.is_private()
Expand Down Expand Up @@ -667,7 +670,8 @@ impl Ipv4Addr {
/// // The broadcast address is not considered as reserved for future use by this implementation
/// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_reserved(), false);
/// ```
pub fn is_reserved(&self) -> bool {
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
pub const fn is_reserved(&self) -> bool {
self.octets()[0] & 240 == 240 && !self.is_broadcast()
}

Expand Down Expand Up @@ -709,9 +713,10 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_broadcast(), true);
/// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_broadcast(), false);
/// ```
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
#[stable(since = "1.7.0", feature = "ip_17")]
pub fn is_broadcast(&self) -> bool {
self == &Self::BROADCAST
pub const fn is_broadcast(&self) -> bool {
u32::from_be_bytes(self.octets()) == u32::from_be_bytes(Self::BROADCAST.octets())
}

/// Returns [`true`] if this address is in a range designated for documentation.
Expand Down Expand Up @@ -762,10 +767,13 @@ impl Ipv4Addr {
/// Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 767)
/// );
/// ```
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_ipv6_compatible(&self) -> Ipv6Addr {
pub const fn to_ipv6_compatible(&self) -> Ipv6Addr {
let [a, b, c, d] = self.octets();
Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d])
Ipv6Addr {
inner: c::in6_addr { s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d] },
}
}

/// Converts this address to an IPv4-mapped [`IPv6` address].
Expand All @@ -782,10 +790,13 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).to_ipv6_mapped(),
/// Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 49152, 767));
/// ```
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_ipv6_mapped(&self) -> Ipv6Addr {
pub const fn to_ipv6_mapped(&self) -> Ipv6Addr {
let [a, b, c, d] = self.octets();
Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d])
Ipv6Addr {
inner: c::in6_addr { s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d] },
}
}
}

Expand Down
19 changes: 18 additions & 1 deletion src/test/ui/consts/std/net/ipv4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#![feature(ip)]
#![feature(const_ipv4)]

use std::net::Ipv4Addr;
use std::net::{Ipv4Addr, Ipv6Addr};

fn main() {
const IP_ADDRESS: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
Expand All @@ -24,6 +24,9 @@ fn main() {
const IS_LINK_LOCAL : bool = IP_ADDRESS.is_link_local();
assert!(!IS_LINK_LOCAL);

const IS_GLOBAL : bool = IP_ADDRESS.is_global();
assert!(!IS_GLOBAL);

const IS_SHARED : bool = IP_ADDRESS.is_shared();
assert!(!IS_SHARED);

Expand All @@ -33,9 +36,23 @@ fn main() {
const IS_BENCHMARKING : bool = IP_ADDRESS.is_benchmarking();
assert!(!IS_BENCHMARKING);

const IS_RESERVED : bool = IP_ADDRESS.is_reserved();
assert!(!IS_RESERVED);

const IS_MULTICAST : bool = IP_ADDRESS.is_multicast();
assert!(!IS_MULTICAST);

const IS_BROADCAST : bool = IP_ADDRESS.is_broadcast();
assert!(!IS_BROADCAST);

const IS_DOCUMENTATION : bool = IP_ADDRESS.is_documentation();
assert!(!IS_DOCUMENTATION);

const IP_V6_COMPATIBLE : Ipv6Addr = IP_ADDRESS.to_ipv6_compatible();
assert_eq!(IP_V6_COMPATIBLE,
Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 1]));

const IP_V6_MAPPED : Ipv6Addr = IP_ADDRESS.to_ipv6_mapped();
assert_eq!(IP_V6_MAPPED,
Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1]));
}

0 comments on commit 0c77257

Please sign in to comment.