diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 111b1ef99..e020d63c9 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -16,7 +16,9 @@ jobs: ref: refs/pull/${{ github.event.number }}/head - uses: actions/checkout@v2 if: github.event_name != 'pull_request_target' - - run: sed -n 's,^rust-version = "\(.*\)"$,RUSTUP_TOOLCHAIN=\1,p' Cargo.toml >> $GITHUB_ENV + # TODO update when stable Rust 1.65 is out. + #- run: sed -n 's,^rust-version = "\(.*\)"$,RUSTUP_TOOLCHAIN=\1,p' Cargo.toml >> $GITHUB_ENV + - run: echo RUSTUP_TOOLCHAIN=beta >> $GITHUB_ENV - run: rustup toolchain install $RUSTUP_TOOLCHAIN - run: rustup component add clippy - uses: actions-rs/clippy-check@v1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 160f6452f..3f03cc79b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,8 +20,9 @@ jobs: # Test on stable, MSRV, and nightly. # Failure is permitted on nightly. rust: - - stable - - 1.61.0 + # TODO update when stable Rust 1.65 is out. + #- stable + - beta - nightly features: @@ -41,6 +42,7 @@ jobs: - std medium-ethernet proto-ipv6 socket-tcp - std medium-ethernet medium-ip proto-ipv4 socket-icmp socket-tcp - std medium-ip proto-ipv6 socket-icmp socket-tcp + - std medium-ip proto-ipv4 proto-ipv6 socket-tcp socket-udp # Test features chosen to be as aggressive as possible. - std medium-ethernet medium-ip medium-ieee802154 proto-ipv4 proto-ipv6 socket-raw socket-udp socket-tcp socket-icmp socket-dns async @@ -64,8 +66,9 @@ jobs: # Test on stable, MSRV, and nightly. # Failure is permitted on nightly. rust: - - stable - - 1.61.0 + # TODO update when stable Rust 1.65 is out. + #- stable + - beta - nightly features: diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e7cbbf7d..d12c4c73b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Remove IpAddress::Unspecified - When sending packets with a raw socket, the source IP address is sent unmodified (it was previously replaced with the interface's address if it was unspecified). - Fix enable `defmt/alloc` if `alloc` or `std` is enabled. -- Minimum Supported Rust Version (MSRV) **bumped** from 1.56 to 1.60 +- Minimum Supported Rust Version (MSRV) **bumped** from 1.56 to 1.65 ## [0.8.1] - 2022-05-12 diff --git a/Cargo.toml b/Cargo.toml index 994b9e644..29432b64d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "smoltcp" version = "0.8.1" edition = "2018" -rust-version = "1.61" +rust-version = "1.65" authors = ["whitequark "] description = "A TCP/IP stack designed for bare-metal, real-time systems without a heap." documentation = "https://docs.rs/smoltcp/" diff --git a/README.md b/README.md index 042f1c473..61de6ca0f 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,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.61 and later. +and compiles on stable Rust 1.65 and later. _smoltcp_ achieves [~Gbps of throughput](#examplesbenchmarkrs) when tested against the Linux TCP stack in loopback mode. diff --git a/examples/utils.rs b/examples/utils.rs index 8473c7303..fc3193593 100644 --- a/examples/utils.rs +++ b/examples/utils.rs @@ -159,7 +159,7 @@ pub fn parse_middleware_options( loopback: bool, ) -> FaultInjector>>> where - D: for<'a> Device<'a>, + D: Device, { let drop_chance = matches .opt_str("drop-chance") diff --git a/fuzz/utils.rs b/fuzz/utils.rs index 89329d99d..206443420 100644 --- a/fuzz/utils.rs +++ b/fuzz/utils.rs @@ -93,7 +93,7 @@ pub fn parse_middleware_options( loopback: bool, ) -> FaultInjector>>> where - D: for<'a> Device<'a>, + D: Device, { let drop_chance = matches .opt_str("drop-chance") diff --git a/src/iface/interface/mod.rs b/src/iface/interface/mod.rs index b604c2397..6e9c0bb16 100644 --- a/src/iface/interface/mod.rs +++ b/src/iface/interface/mod.rs @@ -79,7 +79,7 @@ impl<'a> OutPackets<'a> { } #[allow(unused)] -#[cfg(feature = "proto-ipv4")] +#[cfg(feature = "proto-ipv4-fragmentation")] pub(crate) struct Ipv4OutPacket<'a> { /// The buffer that holds the unfragmented 6LoWPAN packet. buffer: ManagedSlice<'a, u8>, @@ -563,7 +563,7 @@ let iface = builder.finalize(&mut device); /// [neighbor_cache]: #method.neighbor_cache pub fn finalize(self, device: &mut D) -> Interface<'a> where - D: for<'d> Device<'d> + ?Sized, + D: Device + ?Sized, { let caps = device.capabilities(); @@ -905,7 +905,7 @@ impl<'a> Interface<'a> { timestamp: Instant, ) -> Result where - D: for<'d> Device<'d> + ?Sized, + D: Device + ?Sized, { self.inner.now = timestamp; @@ -947,7 +947,7 @@ impl<'a> Interface<'a> { timestamp: Instant, ) -> Result where - D: for<'d> Device<'d> + ?Sized, + D: Device + ?Sized, { self.inner.now = timestamp; @@ -1047,7 +1047,7 @@ impl<'a> Interface<'a> { sockets: &mut SocketSet<'_>, ) -> Result where - D: for<'d> Device<'d> + ?Sized, + D: Device + ?Sized, { self.inner.now = timestamp; @@ -1152,7 +1152,7 @@ impl<'a> Interface<'a> { fn socket_ingress(&mut self, device: &mut D, sockets: &mut SocketSet<'_>) -> bool where - D: for<'d> Device<'d> + ?Sized, + D: Device + ?Sized, { let mut processed_any = false; let Self { @@ -1208,7 +1208,7 @@ impl<'a> Interface<'a> { fn socket_egress(&mut self, device: &mut D, sockets: &mut SocketSet<'_>) -> bool where - D: for<'d> Device<'d> + ?Sized, + D: Device + ?Sized, { let Self { inner, @@ -1318,7 +1318,7 @@ impl<'a> Interface<'a> { #[cfg(feature = "proto-igmp")] fn igmp_egress(&mut self, device: &mut D) -> Result where - D: for<'d> Device<'d> + ?Sized, + D: Device + ?Sized, { match self.inner.igmp_report_state { IgmpReportState::ToSpecificQuery { @@ -1384,7 +1384,7 @@ impl<'a> Interface<'a> { #[cfg(feature = "proto-ipv4-fragmentation")] fn ipv4_egress(&mut self, device: &mut D) -> Result where - D: for<'d> Device<'d> + ?Sized, + D: Device + ?Sized, { // Reset the buffer when we transmitted everything. if self.out_packets.ipv4_out_packet.finished() { @@ -1422,7 +1422,7 @@ impl<'a> Interface<'a> { #[cfg(feature = "proto-sixlowpan-fragmentation")] fn sixlowpan_egress(&mut self, device: &mut D) -> Result where - D: for<'d> Device<'d> + ?Sized, + D: Device + ?Sized, { // Reset the buffer when we transmitted everything. if self.out_packets.sixlowpan_out_packet.finished() { diff --git a/src/lib.rs b/src/lib.rs index 08d16c085..74ff6bba7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,7 +65,7 @@ //! //! # Minimum Supported Rust Version (MSRV) //! -//! This crate is guaranteed to compile on stable Rust 1.61 and up with any valid set of features. +//! This crate is guaranteed to compile on stable Rust 1.65 and up with any valid set of features. //! It *might* compile on older versions but that may change in any new patch release. //! //! The exception is when using the `defmt` feature, in which case `defmt`'s MSRV applies, which diff --git a/src/phy/fault_injector.rs b/src/phy/fault_injector.rs index 6a83bf759..bf6bc6528 100644 --- a/src/phy/fault_injector.rs +++ b/src/phy/fault_injector.rs @@ -94,13 +94,13 @@ impl State { /// adverse network conditions (such as random packet loss or corruption), or software /// or hardware limitations (such as a limited number or size of usable network buffers). #[derive(Debug)] -pub struct FaultInjector Device<'a>> { +pub struct FaultInjector { inner: D, state: RefCell, config: Config, } -impl Device<'a>> FaultInjector { +impl FaultInjector { /// Create a fault injector device, using the given random number generator seed. pub fn new(inner: D, seed: u32) -> FaultInjector { let state = State { @@ -195,12 +195,13 @@ impl Device<'a>> FaultInjector { } } -impl<'a, D> Device<'a> for FaultInjector -where - D: for<'b> Device<'b>, -{ - type RxToken = RxToken<'a, >::RxToken>; - type TxToken = TxToken<'a, >::TxToken>; +impl Device for FaultInjector { + type RxToken<'a> = RxToken<'a, D::RxToken<'a>> + where + Self: 'a; + type TxToken<'a> = TxToken<'a, D::TxToken<'a>> + where + Self: 'a; fn capabilities(&self) -> DeviceCapabilities { let mut caps = self.inner.capabilities(); @@ -210,7 +211,7 @@ where caps } - fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> { + fn receive(&mut self) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { let &mut Self { ref mut inner, ref state, @@ -233,7 +234,7 @@ where }) } - fn transmit(&'a mut self) -> Option { + fn transmit(&mut self) -> Option> { let &mut Self { ref mut inner, ref state, diff --git a/src/phy/fuzz_injector.rs b/src/phy/fuzz_injector.rs index 4be1fc0e2..025517955 100644 --- a/src/phy/fuzz_injector.rs +++ b/src/phy/fuzz_injector.rs @@ -19,14 +19,14 @@ pub trait Fuzzer { #[allow(unused)] #[derive(Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct FuzzInjector Device<'a>, FTx: Fuzzer, FRx: Fuzzer> { +pub struct FuzzInjector { inner: D, fuzz_tx: FTx, fuzz_rx: FRx, } #[allow(unused)] -impl Device<'a>, FTx: Fuzzer, FRx: Fuzzer> FuzzInjector { +impl FuzzInjector { /// Create a fuzz injector device. pub fn new(inner: D, fuzz_tx: FTx, fuzz_rx: FRx) -> FuzzInjector { FuzzInjector { @@ -42,14 +42,17 @@ impl Device<'a>, FTx: Fuzzer, FRx: Fuzzer> FuzzInjector } } -impl<'a, D, FTx, FRx> Device<'a> for FuzzInjector +impl Device for FuzzInjector where - D: for<'b> Device<'b>, - FTx: Fuzzer + 'a, - FRx: Fuzzer + 'a, + FTx: Fuzzer, + FRx: Fuzzer, { - type RxToken = RxToken<'a, >::RxToken, FRx>; - type TxToken = TxToken<'a, >::TxToken, FTx>; + type RxToken<'a> = RxToken<'a, D::RxToken<'a>, FRx> + where + Self: 'a; + type TxToken<'a> = TxToken<'a, D::TxToken<'a>, FTx> + where + Self: 'a; fn capabilities(&self) -> DeviceCapabilities { let mut caps = self.inner.capabilities(); @@ -59,7 +62,7 @@ where caps } - fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> { + fn receive(&mut self) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { let &mut Self { ref mut inner, ref fuzz_rx, @@ -78,7 +81,7 @@ where }) } - fn transmit(&'a mut self) -> Option { + fn transmit(&mut self) -> Option> { let &mut Self { ref mut inner, fuzz_rx: _, diff --git a/src/phy/loopback.rs b/src/phy/loopback.rs index 9b39aed33..e6a317828 100644 --- a/src/phy/loopback.rs +++ b/src/phy/loopback.rs @@ -29,9 +29,9 @@ impl Loopback { } } -impl<'a> Device<'a> for Loopback { - type RxToken = RxToken; - type TxToken = TxToken<'a>; +impl Device for Loopback { + type RxToken<'a> = RxToken; + type TxToken<'a> = TxToken<'a>; fn capabilities(&self) -> DeviceCapabilities { DeviceCapabilities { @@ -41,7 +41,7 @@ impl<'a> Device<'a> for Loopback { } } - fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> { + fn receive(&mut self) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { self.queue.pop_front().map(move |buffer| { let rx = RxToken { buffer }; let tx = TxToken { @@ -51,7 +51,7 @@ impl<'a> Device<'a> for Loopback { }) } - fn transmit(&'a mut self) -> Option { + fn transmit(&mut self) -> Option> { Some(TxToken { queue: &mut self.queue, }) diff --git a/src/phy/mod.rs b/src/phy/mod.rs index 3a7799dab..d95d02ff3 100644 --- a/src/phy/mod.rs +++ b/src/phy/mod.rs @@ -38,16 +38,16 @@ impl<'a> StmPhy { } } -impl<'a> phy::Device<'a> for StmPhy { - type RxToken = StmPhyRxToken<'a>; - type TxToken = StmPhyTxToken<'a>; +impl phy::Device for StmPhy { + type RxToken<'a> = StmPhyRxToken<'a> where Self: 'a; + type TxToken<'a> = StmPhyTxToken<'a> where Self: 'a; - fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> { + fn receive(&mut self) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { Some((StmPhyRxToken(&mut self.rx_buffer[..]), StmPhyTxToken(&mut self.tx_buffer[..]))) } - fn transmit(&'a mut self) -> Option { + fn transmit(&mut self) -> Option> { Some(StmPhyTxToken(&mut self.tx_buffer[..])) } @@ -308,9 +308,13 @@ impl Default for Medium { /// The interface is based on _tokens_, which are types that allow to receive/transmit a /// single packet. The `receive` and `transmit` functions only construct such tokens, the /// real sending/receiving operation are performed when the tokens are consumed. -pub trait Device<'a> { - type RxToken: RxToken + 'a; - type TxToken: TxToken + 'a; +pub trait Device { + type RxToken<'a>: RxToken + where + Self: 'a; + type TxToken<'a>: TxToken + where + Self: 'a; /// Construct a token pair consisting of one receive token and one transmit token. /// @@ -318,10 +322,10 @@ pub trait Device<'a> { /// on the contents of the received packet. For example, this makes it possible to /// handle arbitrarily large ICMP echo ("ping") requests, where the all received bytes /// need to be sent back, without heap allocation. - fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)>; + fn receive(&mut self) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)>; /// Construct a transmit token. - fn transmit(&'a mut self) -> Option; + fn transmit(&mut self) -> Option>; /// Get a description of device capabilities. fn capabilities(&self) -> DeviceCapabilities; diff --git a/src/phy/pcap_writer.rs b/src/phy/pcap_writer.rs index 069e55503..edaf7844f 100644 --- a/src/phy/pcap_writer.rs +++ b/src/phy/pcap_writer.rs @@ -118,7 +118,7 @@ impl PcapSink for T { #[derive(Debug)] pub struct PcapWriter where - D: for<'a> Device<'a>, + D: Device, S: PcapSink, { lower: D, @@ -126,7 +126,7 @@ where mode: PcapMode, } -impl Device<'a>, S: PcapSink> PcapWriter { +impl PcapWriter { /// Creates a packet capture writer. pub fn new(lower: D, mut sink: S, mode: PcapMode) -> PcapWriter { let medium = lower.capabilities().medium; @@ -162,19 +162,22 @@ impl Device<'a>, S: PcapSink> PcapWriter { } } -impl<'a, D, S> Device<'a> for PcapWriter +impl Device for PcapWriter where - D: for<'b> Device<'b>, - S: PcapSink + 'a, + S: PcapSink, { - type RxToken = RxToken<'a, >::RxToken, S>; - type TxToken = TxToken<'a, >::TxToken, S>; + type RxToken<'a> = RxToken<'a, D::RxToken<'a>, S> + where + Self: 'a; + type TxToken<'a> = TxToken<'a, D::TxToken<'a>, S> + where + Self: 'a; fn capabilities(&self) -> DeviceCapabilities { self.lower.capabilities() } - fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> { + fn receive(&mut self) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { let sink = &self.sink; let mode = self.mode; self.lower.receive().map(move |(rx_token, tx_token)| { @@ -192,7 +195,7 @@ where }) } - fn transmit(&'a mut self) -> Option { + fn transmit(&mut self) -> Option> { let sink = &self.sink; let mode = self.mode; self.lower diff --git a/src/phy/raw_socket.rs b/src/phy/raw_socket.rs index b760983a5..0cc45200d 100644 --- a/src/phy/raw_socket.rs +++ b/src/phy/raw_socket.rs @@ -54,9 +54,13 @@ impl RawSocket { } } -impl<'a> Device<'a> for RawSocket { - type RxToken = RxToken; - type TxToken = TxToken; +impl Device for RawSocket { + type RxToken<'a> = RxToken + where + Self: 'a; + type TxToken<'a> = TxToken + where + Self: 'a; fn capabilities(&self) -> DeviceCapabilities { DeviceCapabilities { @@ -66,7 +70,7 @@ impl<'a> Device<'a> for RawSocket { } } - fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> { + fn receive(&mut self) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { let mut lower = self.lower.borrow_mut(); let mut buffer = vec![0; self.mtu]; match lower.recv(&mut buffer[..]) { @@ -83,7 +87,7 @@ impl<'a> Device<'a> for RawSocket { } } - fn transmit(&'a mut self) -> Option { + fn transmit(&mut self) -> Option> { Some(TxToken { lower: self.lower.clone(), }) diff --git a/src/phy/tracer.rs b/src/phy/tracer.rs index fdf5b1cfc..934c6f0f0 100644 --- a/src/phy/tracer.rs +++ b/src/phy/tracer.rs @@ -12,12 +12,12 @@ use crate::{ /// A tracer is a device that pretty prints all packets traversing it /// using the provided writer function, and then passes them to another /// device. -pub struct Tracer Device<'a>> { +pub struct Tracer { inner: D, writer: fn(Instant, Packet), } -impl Device<'a>> Tracer { +impl Tracer { /// Create a tracer device. pub fn new(inner: D, writer: fn(timestamp: Instant, packet: Packet)) -> Tracer { Tracer { inner, writer } @@ -44,18 +44,19 @@ impl Device<'a>> Tracer { } } -impl<'a, D> Device<'a> for Tracer -where - D: for<'b> Device<'b>, -{ - type RxToken = RxToken<>::RxToken>; - type TxToken = TxToken<>::TxToken>; +impl Device for Tracer { + type RxToken<'a> = RxToken> + where + Self: 'a; + type TxToken<'a> = TxToken> + where + Self: 'a; fn capabilities(&self) -> DeviceCapabilities { self.inner.capabilities() } - fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> { + fn receive(&mut self) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { let &mut Self { ref mut inner, writer, @@ -77,7 +78,7 @@ where }) } - fn transmit(&'a mut self) -> Option { + fn transmit(&mut self) -> Option> { let &mut Self { ref mut inner, writer, diff --git a/src/phy/tuntap_interface.rs b/src/phy/tuntap_interface.rs index 6792a7be5..7bc2aa0d9 100644 --- a/src/phy/tuntap_interface.rs +++ b/src/phy/tuntap_interface.rs @@ -40,9 +40,9 @@ impl TunTapInterface { } } -impl<'a> Device<'a> for TunTapInterface { - type RxToken = RxToken; - type TxToken = TxToken; +impl Device for TunTapInterface { + type RxToken<'a> = RxToken; + type TxToken<'a> = TxToken; fn capabilities(&self) -> DeviceCapabilities { DeviceCapabilities { @@ -52,7 +52,7 @@ impl<'a> Device<'a> for TunTapInterface { } } - fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> { + fn receive(&mut self) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { let mut lower = self.lower.borrow_mut(); let mut buffer = vec![0; self.mtu]; match lower.recv(&mut buffer[..]) { @@ -69,7 +69,7 @@ impl<'a> Device<'a> for TunTapInterface { } } - fn transmit(&'a mut self) -> Option { + fn transmit(&mut self) -> Option> { Some(TxToken { lower: self.lower.clone(), })