diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 7aa762352..452f62eeb 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -1,6 +1,6 @@ on: push: - branches: [ staging, trying ] + branches: [staging, trying] pull_request_target: name: Clippy check @@ -17,7 +17,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: 1.53.0 + toolchain: nightly override: true components: clippy - uses: actions-rs/clippy-check@v1 diff --git a/.github/workflows/rustfmt.yaml b/.github/workflows/rustfmt.yaml index 3d065a20e..d68863c41 100644 --- a/.github/workflows/rustfmt.yaml +++ b/.github/workflows/rustfmt.yaml @@ -1,6 +1,6 @@ on: push: - branches: [ staging, trying ] + branches: [staging, trying] pull_request: name: Rustfmt check @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: nightly profile: minimal components: rustfmt - name: Check fmt diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2b19a3889..09ad18279 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,6 @@ on: push: - branches: [ staging, trying ] + branches: [staging, trying] pull_request: name: Test @@ -20,8 +20,8 @@ jobs: # Test on stable, MSRV 1.46, and nightly. # Failure is permitted on nightly. rust: - - stable - - 1.56.0 + #- stable + #- 1.56.0 - nightly features: @@ -67,8 +67,8 @@ jobs: # Test on stable, MSRV 1.46, and nightly. # Failure is permitted on nightly. rust: - - stable - - 1.56.0 + #- stable + #- 1.56.0 - nightly features: diff --git a/examples/dhcp_client.rs b/examples/dhcp_client.rs index 456668e37..d220c3bc0 100644 --- a/examples/dhcp_client.rs +++ b/examples/dhcp_client.rs @@ -94,10 +94,7 @@ fn main() { } } -fn set_ipv4_addr(iface: &mut Interface<'_, DeviceT>, cidr: Ipv4Cidr) -where - DeviceT: for<'d> Device<'d>, -{ +fn set_ipv4_addr(iface: &mut Interface<'_, DeviceT>, cidr: Ipv4Cidr) { iface.update_ip_addrs(|addrs| { let dest = addrs.iter_mut().next().unwrap(); *dest = IpCidr::Ipv4(cidr); diff --git a/examples/utils.rs b/examples/utils.rs index f82dd9a08..a98384098 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.rs b/src/iface/interface.rs index 50f9d0f99..b1c5b6b18 100644 --- a/src/iface/interface.rs +++ b/src/iface/interface.rs @@ -19,7 +19,7 @@ use crate::{Error, Result}; /// The network interface logically owns a number of other data structures; to avoid /// a dependency on heap allocation, it instead owns a `BorrowMut<[T]>`, which can be /// a `&mut [T]`, or `Vec` if a heap is available. -pub struct Interface<'a, DeviceT: for<'d> Device<'d>> { +pub struct Interface<'a, DeviceT: Device> { device: DeviceT, sockets: SocketSet<'a>, inner: InterfaceInner<'a>, @@ -53,7 +53,7 @@ struct InterfaceInner<'a> { } /// A builder structure used for creating a network interface. -pub struct InterfaceBuilder<'a, DeviceT: for<'d> Device<'d>> { +pub struct InterfaceBuilder<'a, DeviceT: Device> { device: DeviceT, #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))] hardware_addr: Option, @@ -73,10 +73,7 @@ pub struct InterfaceBuilder<'a, DeviceT: for<'d> Device<'d>> { ipv4_multicast_groups: ManagedMap<'a, Ipv4Address, ()>, } -impl<'a, DeviceT> InterfaceBuilder<'a, DeviceT> -where - DeviceT: for<'d> Device<'d>, -{ +impl<'a, DeviceT: Device> InterfaceBuilder<'a, DeviceT> { /// Create a builder used for creating a network interface using the /// given device and address. #[cfg_attr( @@ -465,10 +462,7 @@ enum IgmpReportState { }, } -impl<'a, DeviceT> Interface<'a, DeviceT> -where - DeviceT: for<'d> Device<'d>, -{ +impl<'a, DeviceT: Device> Interface<'a, DeviceT> { /// Add a socket to the interface, and return its handle. /// /// # Panics diff --git a/src/lib.rs b/src/lib.rs index b8653cf0b..e899ddd99 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,7 @@ ), deny(unused) )] +#![feature(generic_associated_types)] //! The _smoltcp_ library is built in a layered structure, with the layers corresponding //! to the levels of API abstraction. Only the highest layers would be used by a typical diff --git a/src/phy/fault_injector.rs b/src/phy/fault_injector.rs index 6a83bf759..32edcd105 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,15 @@ 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> + where + Self: 'a, + = RxToken<'a, D::RxToken<'a>>; + type TxToken<'a> + where + Self: 'a, + = TxToken<'a, D::TxToken<'a>>; fn capabilities(&self) -> DeviceCapabilities { let mut caps = self.inner.capabilities(); @@ -210,7 +213,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 +236,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..852f774de 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,19 @@ 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> + where + Self: 'a, + = RxToken<'a, D::RxToken<'a>, FRx>; + type TxToken<'a> + where + Self: 'a, + = TxToken<'a, D::TxToken<'a>, FTx>; fn capabilities(&self) -> DeviceCapabilities { let mut caps = self.inner.capabilities(); @@ -59,7 +64,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 +83,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 ae4a11819..8e12df99d 100644 --- a/src/phy/mod.rs +++ b/src/phy/mod.rs @@ -20,6 +20,8 @@ An implementation of the [Device](trait.Device.html) trait for a simple hardware Ethernet controller could look as follows: ```rust +# #![feature(generic_associated_types)] + use smoltcp::Result; use smoltcp::phy::{self, DeviceCapabilities, Device, Medium}; use smoltcp::time::Instant; @@ -38,16 +40,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> where Self: 'a = StmPhyRxToken<'a>; + type TxToken<'a> where Self: 'a = StmPhyTxToken<'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[..])) } @@ -312,9 +314,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. /// @@ -322,10 +328,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..2acf3e489 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,24 @@ 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> + where + Self: 'a, + = RxToken<'a, D::RxToken<'a>, S>; + type TxToken<'a> + where + Self: 'a, + = TxToken<'a, D::TxToken<'a>, S>; 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 +197,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 e01438f46..2f4cb09da 100644 --- a/src/phy/raw_socket.rs +++ b/src/phy/raw_socket.rs @@ -48,9 +48,15 @@ impl RawSocket { } } -impl<'a> Device<'a> for RawSocket { - type RxToken = RxToken; - type TxToken = TxToken; +impl Device for RawSocket { + type RxToken<'a> + where + Self: 'a, + = RxToken; + type TxToken<'a> + where + Self: 'a, + = TxToken; fn capabilities(&self) -> DeviceCapabilities { DeviceCapabilities { @@ -60,7 +66,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[..]) { @@ -77,7 +83,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..3d0bca92f 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,21 @@ 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> + where + Self: 'a, + = RxToken>; + type TxToken<'a> + where + Self: 'a, + = TxToken>; 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 +80,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(), })