Skip to content

[DO NOT MERGE] Allow a type implementing phy::Device to contain borrowed data #697

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/clippy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- 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
- run: rustup toolchain install $RUSTUP_TOOLCHAIN
- run: rustup toolchain install beta
- run: rustup component add clippy
- uses: actions-rs/clippy-check@v1
with:
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ jobs:
# Test on stable, MSRV, and nightly.
# Failure is permitted on nightly.
rust:
- stable
- 1.60.0
- beta
- nightly

features:
Expand Down Expand Up @@ -64,8 +63,7 @@ jobs:
# Test on stable, MSRV, and nightly.
# Failure is permitted on nightly.
rust:
- stable
- 1.60.0
- beta
- nightly

features:
Expand Down
2 changes: 1 addition & 1 deletion examples/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ pub fn parse_middleware_options<D>(
loopback: bool,
) -> FaultInjector<Tracer<PcapWriter<D, Box<dyn io::Write>>>>
where
D: for<'a> Device<'a>,
D: Device,
{
let drop_chance = matches
.opt_str("drop-chance")
Expand Down
4 changes: 2 additions & 2 deletions fuzz/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ pub fn add_middleware_options(opts: &mut Options, _free: &mut Vec<&str>) {
);
}

pub fn parse_middleware_options<D>(
pub fn parse_middleware_options<'a, D>(
matches: &mut Matches,
device: D,
loopback: bool,
) -> FaultInjector<Tracer<PcapWriter<D, Box<dyn Write>>>>
where
D: for<'a> Device<'a>,
D: Device<'a>,
{
let drop_chance = matches
.opt_str("drop-chance")
Expand Down
18 changes: 9 additions & 9 deletions src/iface/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ let iface = builder.finalize(&mut device);
/// [neighbor_cache]: #method.neighbor_cache
pub fn finalize<D>(self, device: &mut D) -> Interface<'a>
where
D: for<'d> Device<'d> + ?Sized,
D: Device + ?Sized,
{
let caps = device.capabilities();

Expand Down Expand Up @@ -893,7 +893,7 @@ impl<'a> Interface<'a> {
timestamp: Instant,
) -> Result<bool>
where
D: for<'d> Device<'d> + ?Sized,
D: Device + ?Sized,
{
self.inner.now = timestamp;

Expand Down Expand Up @@ -935,7 +935,7 @@ impl<'a> Interface<'a> {
timestamp: Instant,
) -> Result<bool>
where
D: for<'d> Device<'d> + ?Sized,
D: Device + ?Sized,
{
self.inner.now = timestamp;

Expand Down Expand Up @@ -1035,7 +1035,7 @@ impl<'a> Interface<'a> {
sockets: &mut SocketSet<'_>,
) -> Result<bool>
where
D: for<'d> Device<'d> + ?Sized,
D: Device + ?Sized,
{
self.inner.now = timestamp;

Expand Down Expand Up @@ -1140,7 +1140,7 @@ impl<'a> Interface<'a> {

fn socket_ingress<D>(&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 {
Expand Down Expand Up @@ -1196,7 +1196,7 @@ impl<'a> Interface<'a> {

fn socket_egress<D>(&mut self, device: &mut D, sockets: &mut SocketSet<'_>) -> bool
where
D: for<'d> Device<'d> + ?Sized,
D: Device + ?Sized,
{
let Self {
inner,
Expand Down Expand Up @@ -1306,7 +1306,7 @@ impl<'a> Interface<'a> {
#[cfg(feature = "proto-igmp")]
fn igmp_egress<D>(&mut self, device: &mut D) -> Result<bool>
where
D: for<'d> Device<'d> + ?Sized,
D: Device + ?Sized,
{
match self.inner.igmp_report_state {
IgmpReportState::ToSpecificQuery {
Expand Down Expand Up @@ -1372,7 +1372,7 @@ impl<'a> Interface<'a> {
#[cfg(feature = "proto-ipv4-fragmentation")]
fn ipv4_egress<D>(&mut self, device: &mut D) -> Result<bool>
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() {
Expand Down Expand Up @@ -1410,7 +1410,7 @@ impl<'a> Interface<'a> {
#[cfg(feature = "proto-sixlowpan-fragmentation")]
fn sixlowpan_egress<D>(&mut self, device: &mut D) -> Result<bool>
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() {
Expand Down
21 changes: 13 additions & 8 deletions src/phy/fault_injector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<D: for<'a> Device<'a>> {
pub struct FaultInjector<D: Device> {
inner: D,
state: RefCell<State>,
config: Config,
}

impl<D: for<'a> Device<'a>> FaultInjector<D> {
impl<D: Device> FaultInjector<D> {
/// Create a fault injector device, using the given random number generator seed.
pub fn new(inner: D, seed: u32) -> FaultInjector<D> {
let state = State {
Expand Down Expand Up @@ -195,12 +195,17 @@ impl<D: for<'a> Device<'a>> FaultInjector<D> {
}
}

impl<'a, D> Device<'a> for FaultInjector<D>
impl<D> Device for FaultInjector<D>
where
D: for<'b> Device<'b>,
D: Device,
{
type RxToken = RxToken<'a, <D as Device<'a>>::RxToken>;
type TxToken = TxToken<'a, <D as Device<'a>>::TxToken>;
type RxToken<'a> = RxToken<'a, <D as Device>::RxToken<'a>>
where
Self: 'a;

type TxToken<'a> = TxToken<'a, <D as Device>::TxToken<'a>>
where
Self: 'a;

fn capabilities(&self) -> DeviceCapabilities {
let mut caps = self.inner.capabilities();
Expand All @@ -210,7 +215,7 @@ where
caps
}

fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
fn receive<'a>(&'a mut self) -> Option<(Self::RxToken<'a>, Self::TxToken<'a>)> {
let &mut Self {
ref mut inner,
ref state,
Expand All @@ -233,7 +238,7 @@ where
})
}

fn transmit(&'a mut self) -> Option<Self::TxToken> {
fn transmit<'a>(&'a mut self) -> Option<Self::TxToken<'a>> {
let &mut Self {
ref mut inner,
ref state,
Expand Down
25 changes: 15 additions & 10 deletions src/phy/fuzz_injector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ pub trait Fuzzer {
#[allow(unused)]
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct FuzzInjector<D: for<'a> Device<'a>, FTx: Fuzzer, FRx: Fuzzer> {
pub struct FuzzInjector<D: Device, FTx: Fuzzer, FRx: Fuzzer> {
inner: D,
fuzz_tx: FTx,
fuzz_rx: FRx,
}

#[allow(unused)]
impl<D: for<'a> Device<'a>, FTx: Fuzzer, FRx: Fuzzer> FuzzInjector<D, FTx, FRx> {
impl<D: Device, FTx: Fuzzer, FRx: Fuzzer> FuzzInjector<D, FTx, FRx> {
/// Create a fuzz injector device.
pub fn new(inner: D, fuzz_tx: FTx, fuzz_rx: FRx) -> FuzzInjector<D, FTx, FRx> {
FuzzInjector {
Expand All @@ -42,14 +42,19 @@ impl<D: for<'a> Device<'a>, FTx: Fuzzer, FRx: Fuzzer> FuzzInjector<D, FTx, FRx>
}
}

impl<'a, D, FTx, FRx> Device<'a> for FuzzInjector<D, FTx, FRx>
impl<D, FTx, FRx> Device for FuzzInjector<D, FTx, FRx>
where
D: for<'b> Device<'b>,
FTx: Fuzzer + 'a,
FRx: Fuzzer + 'a,
D: Device,
FTx: Fuzzer,
FRx: Fuzzer,
{
type RxToken = RxToken<'a, <D as Device<'a>>::RxToken, FRx>;
type TxToken = TxToken<'a, <D as Device<'a>>::TxToken, FTx>;
type RxToken<'a> = RxToken<'a, <D as Device>::RxToken<'a>, FRx>
where
Self: 'a;

type TxToken<'a> = TxToken<'a, <D as Device>::TxToken<'a>, FTx>
where
Self: 'a;

fn capabilities(&self) -> DeviceCapabilities {
let mut caps = self.inner.capabilities();
Expand All @@ -59,7 +64,7 @@ where
caps
}

fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
fn receive<'a>(&'a mut self) -> Option<(Self::RxToken<'a>, Self::TxToken<'a>)> {
let &mut Self {
ref mut inner,
ref fuzz_rx,
Expand All @@ -78,7 +83,7 @@ where
})
}

fn transmit(&'a mut self) -> Option<Self::TxToken> {
fn transmit<'a>(&'a mut self) -> Option<Self::TxToken<'a>> {
let &mut Self {
ref mut inner,
fuzz_rx: _,
Expand Down
10 changes: 5 additions & 5 deletions src/phy/loopback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -41,7 +41,7 @@ impl<'a> Device<'a> for Loopback {
}
}

fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
fn receive<'a>(&'a mut self) -> Option<(Self::RxToken<'a>, Self::TxToken<'a>)> {
self.queue.pop_front().map(move |buffer| {
let rx = RxToken { buffer };
let tx = TxToken {
Expand All @@ -51,7 +51,7 @@ impl<'a> Device<'a> for Loopback {
})
}

fn transmit(&'a mut self) -> Option<Self::TxToken> {
fn transmit<'a>(&'a mut self) -> Option<Self::TxToken<'a>> {
Some(TxToken {
queue: &mut self.queue,
})
Expand Down
27 changes: 16 additions & 11 deletions src/phy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct StmPhy {
tx_buffer: [u8; 1536],
}

impl<'a> StmPhy {
impl StmPhy {
fn new() -> StmPhy {
StmPhy {
rx_buffer: [0; 1536],
Expand All @@ -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>;
type TxToken<'a> = StmPhyTxToken<'a>;

fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
fn receive<'a>(&'a mut self) -> Option<(Self::RxToken<'a>, Self::TxToken<'a>)> {
Some((StmPhyRxToken(&mut self.rx_buffer[..]),
StmPhyTxToken(&mut self.tx_buffer[..])))
}

fn transmit(&'a mut self) -> Option<Self::TxToken> {
fn transmit<'a>(&'a mut self) -> Option<Self::TxToken<'a>> {
Some(StmPhyTxToken(&mut self.tx_buffer[..]))
}

Expand Down Expand Up @@ -308,20 +308,25 @@ 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.
///
/// The additional transmit token makes it possible to generate a reply packet based
/// 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<'a>(&'a mut self) -> Option<(Self::RxToken<'a>, Self::TxToken<'a>)>;

/// Construct a transmit token.
fn transmit(&'a mut self) -> Option<Self::TxToken>;
fn transmit<'a>(&'a mut self) -> Option<Self::TxToken<'a>>;

/// Get a description of device capabilities.
fn capabilities(&self) -> DeviceCapabilities;
Expand Down
Loading