diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 498e606..b4d11eb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,11 +11,11 @@ jobs: continue-on-error: ${{ matrix.rust == 'nightly' }} strategy: matrix: - # Test on stable, MSRV 1.36, and nightly. + # Test on stable, MSRV 1.40, and nightly. # Failure is permitted on nightly. rust: - stable - - 1.36.0 + - 1.40.0 - nightly features: @@ -57,11 +57,11 @@ jobs: continue-on-error: ${{ matrix.rust == 'nightly' }} strategy: matrix: - # Test on stable, MSRV 1.36, and nightly. + # Test on stable, MSRV 1.40, and nightly. # Failure is permitted on nightly. rust: - stable - - 1.36.0 + - 1.40.0 - nightly features: diff --git a/README.md b/README.md index a240a15..edcc963 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ include complicated compile-time computations, such as macro or type tricks, eve at cost of performance degradation. _smoltcp_ does not need heap allocation *at all*, is [extensively documented][docs], -and compiles on stable Rust 1.36 and later. +and compiles on stable Rust 1.40 and later. _smoltcp_ achieves [~Gbps of throughput](#examplesbenchmarkrs) when tested against the Linux TCP stack in loopback mode. diff --git a/src/iface/ethernet.rs b/src/iface/ethernet.rs index f6a1267..0a0d13e 100644 --- a/src/iface/ethernet.rs +++ b/src/iface/ethernet.rs @@ -678,7 +678,6 @@ impl<'b, 'c, 'e, DeviceT> Interface<'b, 'c, 'e, DeviceT> Socket::Tcp(ref mut socket) => socket.dispatch(timestamp, &caps, |response| respond!(IpPacket::Tcp(response))), - Socket::__Nonexhaustive(_) => unreachable!() }; match (device_result, socket_result) { @@ -800,7 +799,8 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { .filter_map( |addr| match *addr { IpCidr::Ipv4(cidr) => Some(cidr.address()), - _ => None, + #[cfg(feature = "proto-ipv6")] + IpCidr::Ipv6(_) => None }) .next() } @@ -886,8 +886,6 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { Ok(None) } } - - _ => Err(Error::Unrecognized) } } @@ -1253,7 +1251,6 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { } } } - _ => return Err(Error::Unrecognized), } } self.process_nxt_hdr(sockets, timestamp, ipv6_repr, hbh_repr.next_header, @@ -1421,8 +1418,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { }; Ok(self.icmpv6_reply(ipv6_repr, icmpv6_reply_repr)) }, - IpRepr::Unspecified { .. } | - IpRepr::__Nonexhaustive => Err(Error::Unaddressable), + IpRepr::Unspecified { .. } => Err(Error::Unaddressable), } } @@ -1467,7 +1463,6 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { let dst_hardware_addr = match arp_repr { ArpRepr::EthernetIpv4 { target_hardware_addr, .. } => target_hardware_addr, - _ => unreachable!() }; self.dispatch_ethernet(tx_token, timestamp, arp_repr.buffer_len(), |mut frame| { @@ -1555,8 +1550,6 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { b[12], b[13], b[14], b[15], ])), - IpAddress::__Nonexhaustive => - unreachable!() }; if let Some(hardware_addr) = hardware_addr { return Ok((hardware_addr, tx_token)) @@ -1770,7 +1763,7 @@ mod test { impl phy::TxToken for MockTxToken { fn consume(self, _: Instant, _: usize, _: F) -> Result where F: FnOnce(&mut [u8]) -> Result { - Err(Error::__Nonexhaustive) + Err(Error::Unaddressable) } } diff --git a/src/lib.rs b/src/lib.rs index 0eb50e4..7d18e89 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -116,6 +116,7 @@ pub mod dhcp; /// The error type for the networking stack. #[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[non_exhaustive] pub enum Error { /// An operation cannot proceed because a buffer is empty or full. Exhausted, @@ -148,9 +149,6 @@ pub enum Error { /// An incoming packet was recognized but contradicted internal state. /// E.g. a TCP packet addressed to a socket that doesn't exist. Dropped, - - #[doc(hidden)] - __Nonexhaustive } /// The result type for the networking stack. @@ -169,7 +167,6 @@ impl fmt::Display for Error { Error::Fragmented => write!(f, "fragmented packet"), Error::Malformed => write!(f, "malformed packet"), Error::Dropped => write!(f, "dropped by socket"), - Error::__Nonexhaustive => unreachable!() } } } diff --git a/src/socket/mod.rs b/src/socket/mod.rs index c81b2f0..d7a971b 100644 --- a/src/socket/mod.rs +++ b/src/socket/mod.rs @@ -11,7 +11,6 @@ The interface implemented by this module uses explicit buffering: you decide on size for a buffer, allocate it, and let the networking stack use it. */ -use core::marker::PhantomData; use crate::time::Instant; mod meta; @@ -91,8 +90,6 @@ pub enum Socket<'a> { Udp(UdpSocket<'a>), #[cfg(feature = "socket-tcp")] Tcp(TcpSocket<'a>), - #[doc(hidden)] - __Nonexhaustive(PhantomData<&'a ()>) } macro_rules! dispatch_socket { @@ -112,7 +109,6 @@ macro_rules! dispatch_socket { &$( $mut_ )* Socket::Udp(ref $( $mut_ )* $socket) => $code, #[cfg(feature = "socket-tcp")] &$( $mut_ )* Socket::Tcp(ref $( $mut_ )* $socket) => $code, - &$( $mut_ )* Socket::__Nonexhaustive(_) => unreachable!() } }; } @@ -154,9 +150,10 @@ macro_rules! from_socket { impl<'a> AnySocket<'a> for $socket { fn downcast<'c>(ref_: SocketRef<'c, Socket<'a>>) -> Option> { - match SocketRef::into_inner(ref_) { - &mut Socket::$variant(ref mut socket) => Some(SocketRef::new(socket)), - _ => None, + if let Socket::$variant(ref mut socket) = SocketRef::into_inner(ref_) { + Some(SocketRef::new(socket)) + } else { + None } } } diff --git a/src/socket/raw.rs b/src/socket/raw.rs index 2b99792..e4e60ed 100644 --- a/src/socket/raw.rs +++ b/src/socket/raw.rs @@ -257,7 +257,6 @@ impl<'a> RawSocket<'a> { Ok((IpRepr::Ipv6(ipv6_repr), packet.payload())) } IpVersion::Unspecified => unreachable!(), - IpVersion::__Nonexhaustive => unreachable!() } } diff --git a/src/socket/set.rs b/src/socket/set.rs index 8f0bc01..883bed8 100644 --- a/src/socket/set.rs +++ b/src/socket/set.rs @@ -155,7 +155,6 @@ impl<'a, 'b: 'a> Set<'a, 'b> { } else { socket.close() }, - Socket::__Nonexhaustive(_) => unreachable!() } } if may_remove { diff --git a/src/wire/arp.rs b/src/wire/arp.rs index 150adbf..e213b29 100644 --- a/src/wire/arp.rs +++ b/src/wire/arp.rs @@ -252,6 +252,7 @@ use crate::wire::{EthernetAddress, Ipv4Address}; /// A high-level representation of an Address Resolution Protocol packet. #[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[non_exhaustive] pub enum Repr { /// An Ethernet and IPv4 Address Resolution Protocol packet. EthernetIpv4 { @@ -261,8 +262,6 @@ pub enum Repr { target_hardware_addr: EthernetAddress, target_protocol_addr: Ipv4Address }, - #[doc(hidden)] - __Nonexhaustive } impl Repr { @@ -292,7 +291,6 @@ impl Repr { pub fn buffer_len(&self) -> usize { match *self { Repr::EthernetIpv4 { .. } => field::TPA(6, 4).end, - Repr::__Nonexhaustive => unreachable!() } } @@ -314,7 +312,6 @@ impl Repr { packet.set_target_hardware_addr(target_hardware_addr.as_bytes()); packet.set_target_protocol_addr(target_protocol_addr.as_bytes()); }, - Repr::__Nonexhaustive => unreachable!() } } } @@ -351,7 +348,6 @@ impl fmt::Display for Repr { target_hardware_addr, target_protocol_addr, operation) }, - Repr::__Nonexhaustive => unreachable!() } } } diff --git a/src/wire/icmpv4.rs b/src/wire/icmpv4.rs index fae318a..5748c89 100644 --- a/src/wire/icmpv4.rs +++ b/src/wire/icmpv4.rs @@ -366,6 +366,7 @@ impl> AsRef<[u8]> for Packet { /// A high-level representation of an Internet Control Message Protocol version 4 packet header. #[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[non_exhaustive] pub enum Repr<'a> { EchoRequest { ident: u16, @@ -382,8 +383,6 @@ pub enum Repr<'a> { header: Ipv4Repr, data: &'a [u8] }, - #[doc(hidden)] - __Nonexhaustive } impl<'a> Repr<'a> { @@ -446,7 +445,6 @@ impl<'a> Repr<'a> { &Repr::DstUnreachable { header, data, .. } => { field::UNUSED.end + header.buffer_len() + data.len() } - &Repr::__Nonexhaustive => unreachable!() } } @@ -483,8 +481,6 @@ impl<'a> Repr<'a> { let payload = &mut ip_packet.into_inner()[header.buffer_len()..]; payload.copy_from_slice(&data[..]) } - - Repr::__Nonexhaustive => unreachable!() } if checksum_caps.icmpv4.tx() { @@ -526,7 +522,6 @@ impl<'a> fmt::Display for Repr<'a> { Repr::DstUnreachable { reason, .. } => write!(f, "ICMPv4 destination unreachable ({})", reason), - Repr::__Nonexhaustive => unreachable!() } } } diff --git a/src/wire/icmpv6.rs b/src/wire/icmpv6.rs index b3e49a1..bd23244 100644 --- a/src/wire/icmpv6.rs +++ b/src/wire/icmpv6.rs @@ -503,6 +503,7 @@ impl> AsRef<[u8]> for Packet { /// A high-level representation of an Internet Control Message Protocol version 6 packet header. #[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[non_exhaustive] pub enum Repr<'a> { DstUnreachable { reason: DstUnreachable, @@ -538,8 +539,6 @@ pub enum Repr<'a> { #[cfg(feature = "ethernet")] Ndisc(NdiscRepr<'a>), Mld(MldRepr<'a>), - #[doc(hidden)] - __Nonexhaustive } impl<'a> Repr<'a> { @@ -647,7 +646,6 @@ impl<'a> Repr<'a> { &Repr::Mld(mld) => { mld.buffer_len() }, - &Repr::__Nonexhaustive => unreachable!() } } @@ -720,8 +718,6 @@ impl<'a> Repr<'a> { Repr::Mld(mld) => { mld.emit(packet) }, - - Repr::__Nonexhaustive => unreachable!(), } if checksum_caps.icmpv6.tx() { diff --git a/src/wire/ip.rs b/src/wire/ip.rs index 1b6acae..f6f6777 100644 --- a/src/wire/ip.rs +++ b/src/wire/ip.rs @@ -10,14 +10,13 @@ use crate::wire::{Ipv6Address, Ipv6Cidr, Ipv6Packet, Ipv6Repr}; /// Internet protocol version. #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] +#[non_exhaustive] pub enum Version { Unspecified, #[cfg(feature = "proto-ipv4")] Ipv4, #[cfg(feature = "proto-ipv6")] Ipv6, - #[doc(hidden)] - __Nonexhaustive, } impl Version { @@ -44,7 +43,6 @@ impl fmt::Display for Version { Version::Ipv4 => write!(f, "IPv4"), #[cfg(feature = "proto-ipv6")] Version::Ipv6 => write!(f, "IPv6"), - Version::__Nonexhaustive => unreachable!() } } } @@ -85,6 +83,7 @@ impl fmt::Display for Protocol { /// An internetworking address. #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] +#[non_exhaustive] pub enum Address { /// An unspecified address. /// May be used as a placeholder for storage where the address is not assigned yet. @@ -95,8 +94,6 @@ pub enum Address { /// An IPv6 address. #[cfg(feature = "proto-ipv6")] Ipv6(Ipv6Address), - #[doc(hidden)] - __Nonexhaustive } impl Address { @@ -122,7 +119,6 @@ impl Address { Address::Ipv4(ref addr) => addr.as_bytes(), #[cfg(feature = "proto-ipv6")] Address::Ipv6(ref addr) => addr.as_bytes(), - Address::__Nonexhaustive => unreachable!() } } @@ -134,7 +130,6 @@ impl Address { Address::Ipv4(addr) => addr.is_unicast(), #[cfg(feature = "proto-ipv6")] Address::Ipv6(addr) => addr.is_unicast(), - Address::__Nonexhaustive => unreachable!() } } @@ -146,7 +141,6 @@ impl Address { Address::Ipv4(addr) => addr.is_multicast(), #[cfg(feature = "proto-ipv6")] Address::Ipv6(addr) => addr.is_multicast(), - Address::__Nonexhaustive => unreachable!() } } @@ -158,7 +152,6 @@ impl Address { Address::Ipv4(addr) => addr.is_broadcast(), #[cfg(feature = "proto-ipv6")] Address::Ipv6(_) => false, - Address::__Nonexhaustive => unreachable!() } } @@ -170,7 +163,6 @@ impl Address { Address::Ipv4(addr) => addr.is_unspecified(), #[cfg(feature = "proto-ipv6")] Address::Ipv6(addr) => addr.is_unspecified(), - Address::__Nonexhaustive => unreachable!() } } @@ -182,7 +174,6 @@ impl Address { Address::Ipv4(_) => Address::Ipv4(Ipv4Address::UNSPECIFIED), #[cfg(feature = "proto-ipv6")] Address::Ipv6(_) => Address::Ipv6(Ipv6Address::UNSPECIFIED), - Address::__Nonexhaustive => unreachable!() } } @@ -265,7 +256,6 @@ impl fmt::Display for Address { Address::Ipv4(addr) => write!(f, "{}", addr), #[cfg(feature = "proto-ipv6")] Address::Ipv6(addr) => write!(f, "{}", addr), - Address::__Nonexhaustive => unreachable!() } } } @@ -273,13 +263,12 @@ impl fmt::Display for Address { /// A specification of a CIDR block, containing an address and a variable-length /// subnet masking prefix length. #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] +#[non_exhaustive] pub enum Cidr { #[cfg(feature = "proto-ipv4")] Ipv4(Ipv4Cidr), #[cfg(feature = "proto-ipv6")] Ipv6(Ipv6Cidr), - #[doc(hidden)] - __Nonexhaustive, } impl Cidr { @@ -296,8 +285,6 @@ impl Cidr { Address::Ipv6(addr) => Cidr::Ipv6(Ipv6Cidr::new(addr, prefix_len)), Address::Unspecified => panic!("a CIDR block cannot be based on an unspecified address"), - Address::__Nonexhaustive => - unreachable!() } } @@ -308,7 +295,6 @@ impl Cidr { Cidr::Ipv4(cidr) => Address::Ipv4(cidr.address()), #[cfg(feature = "proto-ipv6")] Cidr::Ipv6(cidr) => Address::Ipv6(cidr.address()), - Cidr::__Nonexhaustive => unreachable!() } } @@ -319,7 +305,6 @@ impl Cidr { Cidr::Ipv4(cidr) => cidr.prefix_len(), #[cfg(feature = "proto-ipv6")] Cidr::Ipv6(cidr) => cidr.prefix_len(), - Cidr::__Nonexhaustive => unreachable!() } } @@ -340,9 +325,6 @@ impl Cidr { // a fully unspecified address covers both IPv4 and IPv6, // and no CIDR block can do that. false, - (&Cidr::__Nonexhaustive, _) | - (_, &Address::__Nonexhaustive) => - unreachable!() } } @@ -359,9 +341,6 @@ impl Cidr { #[cfg(all(feature = "proto-ipv6", feature = "proto-ipv4"))] (&Cidr::Ipv4(_), &Cidr::Ipv6(_)) | (&Cidr::Ipv6(_), &Cidr::Ipv4(_)) => false, - (&Cidr::__Nonexhaustive, _) | - (_, &Cidr::__Nonexhaustive) => - unreachable!() } } } @@ -387,7 +366,6 @@ impl fmt::Display for Cidr { Cidr::Ipv4(cidr) => write!(f, "{}", cidr), #[cfg(feature = "proto-ipv6")] Cidr::Ipv6(cidr) => write!(f, "{}", cidr), - Cidr::__Nonexhaustive => unreachable!() } } } @@ -470,6 +448,7 @@ impl> From<(T, u16)> for Endpoint { /// high-level representation for some IP protocol version, or an unspecified representation, /// which permits the `IpAddress::Unspecified` addresses. #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub enum Repr { Unspecified { src_addr: Address, @@ -482,8 +461,6 @@ pub enum Repr { Ipv4(Ipv4Repr), #[cfg(feature = "proto-ipv6")] Ipv6(Ipv6Repr), - #[doc(hidden)] - __Nonexhaustive } #[cfg(feature = "proto-ipv4")] @@ -509,7 +486,6 @@ impl Repr { Repr::Ipv4(_) => Version::Ipv4, #[cfg(feature = "proto-ipv6")] Repr::Ipv6(_) => Version::Ipv6, - Repr::__Nonexhaustive => unreachable!() } } @@ -521,7 +497,6 @@ impl Repr { Repr::Ipv4(repr) => Address::Ipv4(repr.src_addr), #[cfg(feature = "proto-ipv6")] Repr::Ipv6(repr) => Address::Ipv6(repr.src_addr), - Repr::__Nonexhaustive => unreachable!() } } @@ -533,7 +508,6 @@ impl Repr { Repr::Ipv4(repr) => Address::Ipv4(repr.dst_addr), #[cfg(feature = "proto-ipv6")] Repr::Ipv6(repr) => Address::Ipv6(repr.dst_addr), - Repr::__Nonexhaustive => unreachable!() } } @@ -545,7 +519,6 @@ impl Repr { Repr::Ipv4(repr) => repr.protocol, #[cfg(feature = "proto-ipv6")] Repr::Ipv6(repr) => repr.next_header, - Repr::__Nonexhaustive => unreachable!() } } @@ -557,7 +530,6 @@ impl Repr { Repr::Ipv4(repr) => repr.payload_len, #[cfg(feature = "proto-ipv6")] Repr::Ipv6(repr) => repr.payload_len, - Repr::__Nonexhaustive => unreachable!() } } @@ -572,7 +544,6 @@ impl Repr { #[cfg(feature = "proto-ipv6")] Repr::Ipv6(Ipv6Repr { ref mut payload_len, .. }) => *payload_len = length, - Repr::__Nonexhaustive => unreachable!() } } @@ -584,7 +555,6 @@ impl Repr { Repr::Ipv4(Ipv4Repr { hop_limit, .. }) => hop_limit, #[cfg(feature = "proto-ipv6")] Repr::Ipv6(Ipv6Repr { hop_limit, ..}) => hop_limit, - Repr::__Nonexhaustive => unreachable!() } } @@ -711,8 +681,6 @@ impl Repr { &Repr::Unspecified { .. } => panic!("source and destination IP address families do not match"), - - &Repr::__Nonexhaustive => unreachable!() } } @@ -730,8 +698,6 @@ impl Repr { #[cfg(feature = "proto-ipv6")] Repr::Ipv6(repr) => repr.buffer_len(), - Repr::__Nonexhaustive => - unreachable!() } } @@ -749,8 +715,6 @@ impl Repr { #[cfg(feature = "proto-ipv6")] Repr::Ipv6(repr) => repr.emit(&mut Ipv6Packet::new_unchecked(buffer)), - Repr::__Nonexhaustive => - unreachable!() } } diff --git a/src/wire/ipv6option.rs b/src/wire/ipv6option.rs index 18e5dce..7264284 100644 --- a/src/wire/ipv6option.rs +++ b/src/wire/ipv6option.rs @@ -214,6 +214,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Ipv6Option<&'a T> { /// A high-level representation of an IPv6 Extension Header Option. #[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[non_exhaustive] pub enum Repr<'a> { Pad1, PadN(u8), @@ -222,9 +223,6 @@ pub enum Repr<'a> { length: u8, data: &'a [u8] }, - - #[doc(hidden)] - __Nonexhaustive } impl<'a> Repr<'a> { @@ -253,8 +251,6 @@ impl<'a> Repr<'a> { field::DATA(length).end, Repr::Unknown{ length, .. } => field::DATA(length).end, - - Repr::__Nonexhaustive => unreachable!() } } @@ -276,8 +272,6 @@ impl<'a> Repr<'a> { opt.set_data_len(length); opt.data_mut().copy_from_slice(&data[..length as usize]); } - - Repr::__Nonexhaustive => unreachable!() } } } @@ -352,8 +346,6 @@ impl<'a> fmt::Display for Repr<'a> { write!(f, "{} length={} ", Type::PadN, len), Repr::Unknown{ type_, length, .. } => write!(f, "{} length={} ", type_, length), - - Repr::__Nonexhaustive => unreachable!() } } } diff --git a/src/wire/ipv6routing.rs b/src/wire/ipv6routing.rs index 93a2775..f407899 100644 --- a/src/wire/ipv6routing.rs +++ b/src/wire/ipv6routing.rs @@ -389,6 +389,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Header<&'a T> { /// A high-level representation of an IPv6 Routing Header. #[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[non_exhaustive] pub enum Repr<'a> { Type2 { /// The type of header immediately following the Routing header. @@ -417,9 +418,6 @@ pub enum Repr<'a> { /// Vector of addresses, numbered 1 to `n`. addresses: &'a[u8], }, - - #[doc(hidden)] - __Nonexhaustive } @@ -458,8 +456,6 @@ impl<'a> Repr<'a> { &Repr::Rpl { length, .. } | &Repr::Type2 { length, .. } => { field::DATA(length).end } - - &Repr::__Nonexhaustive => unreachable!() } } @@ -485,8 +481,6 @@ impl<'a> Repr<'a> { header.clear_reserved(); header.set_addresses(addresses); } - - Repr::__Nonexhaustive => unreachable!(), } } } @@ -502,8 +496,6 @@ impl<'a> fmt::Display for Repr<'a> { write!(f, "IPv6 Routing next_hdr={} length={} type={} seg_left={} cmpr_i={} cmpr_e={} pad={}", next_header, length, Type::Rpl, segments_left, cmpr_i, cmpr_e, pad) } - - Repr::__Nonexhaustive => unreachable!(), } } }