Skip to content

Commit 71cc55c

Browse files
committed
Allow a type implementing phy::Device to contain borrowed data
Previously, a limitation of Rust's type system required a device to implement `phy::Device<'a>` for all lifetimes, including `'static`, to be able to call methods on `iface::Interface`. This prevented types implementing `phy::Device<'a>` from containing any borrowed data. Now that Rust supports GATs (generic associated types), it is possible to lift this restriction and allow implementations of `phy::Device<'a>` which contain borrowed data.
1 parent 5b3d6fc commit 71cc55c

File tree

11 files changed

+98
-73
lines changed

11 files changed

+98
-73
lines changed

examples/utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ pub fn parse_middleware_options<D>(
159159
loopback: bool,
160160
) -> FaultInjector<Tracer<PcapWriter<D, Box<dyn io::Write>>>>
161161
where
162-
D: for<'a> Device<'a>,
162+
D: Device,
163163
{
164164
let drop_chance = matches
165165
.opt_str("drop-chance")

fuzz/utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,13 @@ pub fn add_middleware_options(opts: &mut Options, _free: &mut Vec<&str>) {
8787
);
8888
}
8989

90-
pub fn parse_middleware_options<D>(
90+
pub fn parse_middleware_options<'a, D>(
9191
matches: &mut Matches,
9292
device: D,
9393
loopback: bool,
9494
) -> FaultInjector<Tracer<PcapWriter<D, Box<dyn Write>>>>
9595
where
96-
D: for<'a> Device<'a>,
96+
D: Device<'a>,
9797
{
9898
let drop_chance = matches
9999
.opt_str("drop-chance")

src/iface/interface.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ let iface = builder.finalize(&mut device);
551551
/// [neighbor_cache]: #method.neighbor_cache
552552
pub fn finalize<D>(self, device: &mut D) -> Interface<'a>
553553
where
554-
D: for<'d> Device<'d> + ?Sized,
554+
D: Device + ?Sized,
555555
{
556556
let caps = device.capabilities();
557557

@@ -893,7 +893,7 @@ impl<'a> Interface<'a> {
893893
timestamp: Instant,
894894
) -> Result<bool>
895895
where
896-
D: for<'d> Device<'d> + ?Sized,
896+
D: Device + ?Sized,
897897
{
898898
self.inner.now = timestamp;
899899

@@ -935,7 +935,7 @@ impl<'a> Interface<'a> {
935935
timestamp: Instant,
936936
) -> Result<bool>
937937
where
938-
D: for<'d> Device<'d> + ?Sized,
938+
D: Device + ?Sized,
939939
{
940940
self.inner.now = timestamp;
941941

@@ -1035,7 +1035,7 @@ impl<'a> Interface<'a> {
10351035
sockets: &mut SocketSet<'_>,
10361036
) -> Result<bool>
10371037
where
1038-
D: for<'d> Device<'d> + ?Sized,
1038+
D: Device + ?Sized,
10391039
{
10401040
self.inner.now = timestamp;
10411041

@@ -1140,7 +1140,7 @@ impl<'a> Interface<'a> {
11401140

11411141
fn socket_ingress<D>(&mut self, device: &mut D, sockets: &mut SocketSet<'_>) -> bool
11421142
where
1143-
D: for<'d> Device<'d> + ?Sized,
1143+
D: Device + ?Sized,
11441144
{
11451145
let mut processed_any = false;
11461146
let Self {
@@ -1196,7 +1196,7 @@ impl<'a> Interface<'a> {
11961196

11971197
fn socket_egress<D>(&mut self, device: &mut D, sockets: &mut SocketSet<'_>) -> bool
11981198
where
1199-
D: for<'d> Device<'d> + ?Sized,
1199+
D: Device + ?Sized,
12001200
{
12011201
let Self {
12021202
inner,
@@ -1306,7 +1306,7 @@ impl<'a> Interface<'a> {
13061306
#[cfg(feature = "proto-igmp")]
13071307
fn igmp_egress<D>(&mut self, device: &mut D) -> Result<bool>
13081308
where
1309-
D: for<'d> Device<'d> + ?Sized,
1309+
D: Device + ?Sized,
13101310
{
13111311
match self.inner.igmp_report_state {
13121312
IgmpReportState::ToSpecificQuery {
@@ -1372,7 +1372,7 @@ impl<'a> Interface<'a> {
13721372
#[cfg(feature = "proto-ipv4-fragmentation")]
13731373
fn ipv4_egress<D>(&mut self, device: &mut D) -> Result<bool>
13741374
where
1375-
D: for<'d> Device<'d> + ?Sized,
1375+
D: Device + ?Sized,
13761376
{
13771377
// Reset the buffer when we transmitted everything.
13781378
if self.out_packets.ipv4_out_packet.finished() {
@@ -1410,7 +1410,7 @@ impl<'a> Interface<'a> {
14101410
#[cfg(feature = "proto-sixlowpan-fragmentation")]
14111411
fn sixlowpan_egress<D>(&mut self, device: &mut D) -> Result<bool>
14121412
where
1413-
D: for<'d> Device<'d> + ?Sized,
1413+
D: Device + ?Sized,
14141414
{
14151415
// Reset the buffer when we transmitted everything.
14161416
if self.out_packets.sixlowpan_out_packet.finished() {

src/phy/fault_injector.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,13 @@ impl State {
9494
/// adverse network conditions (such as random packet loss or corruption), or software
9595
/// or hardware limitations (such as a limited number or size of usable network buffers).
9696
#[derive(Debug)]
97-
pub struct FaultInjector<D: for<'a> Device<'a>> {
97+
pub struct FaultInjector<D: Device> {
9898
inner: D,
9999
state: RefCell<State>,
100100
config: Config,
101101
}
102102

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

198-
impl<'a, D> Device<'a> for FaultInjector<D>
198+
impl<D> Device for FaultInjector<D>
199199
where
200-
D: for<'b> Device<'b>,
200+
D: Device,
201201
{
202-
type RxToken = RxToken<'a, <D as Device<'a>>::RxToken>;
203-
type TxToken = TxToken<'a, <D as Device<'a>>::TxToken>;
202+
type RxToken<'a> = RxToken<'a, <D as Device>::RxToken<'a>>
203+
where
204+
Self: 'a;
205+
206+
type TxToken<'a> = TxToken<'a, <D as Device>::TxToken<'a>>
207+
where
208+
Self: 'a;
204209

205210
fn capabilities(&self) -> DeviceCapabilities {
206211
let mut caps = self.inner.capabilities();
@@ -210,7 +215,7 @@ where
210215
caps
211216
}
212217

213-
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
218+
fn receive<'a>(&'a mut self) -> Option<(Self::RxToken<'a>, Self::TxToken<'a>)> {
214219
let &mut Self {
215220
ref mut inner,
216221
ref state,
@@ -233,7 +238,7 @@ where
233238
})
234239
}
235240

236-
fn transmit(&'a mut self) -> Option<Self::TxToken> {
241+
fn transmit<'a>(&'a mut self) -> Option<Self::TxToken<'a>> {
237242
let &mut Self {
238243
ref mut inner,
239244
ref state,

src/phy/fuzz_injector.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ pub trait Fuzzer {
1919
#[allow(unused)]
2020
#[derive(Debug)]
2121
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
22-
pub struct FuzzInjector<D: for<'a> Device<'a>, FTx: Fuzzer, FRx: Fuzzer> {
22+
pub struct FuzzInjector<D: Device, FTx: Fuzzer, FRx: Fuzzer> {
2323
inner: D,
2424
fuzz_tx: FTx,
2525
fuzz_rx: FRx,
2626
}
2727

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

45-
impl<'a, D, FTx, FRx> Device<'a> for FuzzInjector<D, FTx, FRx>
45+
impl<D, FTx, FRx> Device for FuzzInjector<D, FTx, FRx>
4646
where
47-
D: for<'b> Device<'b>,
48-
FTx: Fuzzer + 'a,
49-
FRx: Fuzzer + 'a,
47+
D: Device,
48+
FTx: Fuzzer,
49+
FRx: Fuzzer,
5050
{
51-
type RxToken = RxToken<'a, <D as Device<'a>>::RxToken, FRx>;
52-
type TxToken = TxToken<'a, <D as Device<'a>>::TxToken, FTx>;
51+
type RxToken<'a> = RxToken<'a, <D as Device>::RxToken<'a>, FRx>
52+
where
53+
Self: 'a;
54+
55+
type TxToken<'a> = TxToken<'a, <D as Device>::TxToken<'a>, FTx>
56+
where
57+
Self: 'a;
5358

5459
fn capabilities(&self) -> DeviceCapabilities {
5560
let mut caps = self.inner.capabilities();
@@ -59,7 +64,7 @@ where
5964
caps
6065
}
6166

62-
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
67+
fn receive<'a>(&'a mut self) -> Option<(Self::RxToken<'a>, Self::TxToken<'a>)> {
6368
let &mut Self {
6469
ref mut inner,
6570
ref fuzz_rx,
@@ -78,7 +83,7 @@ where
7883
})
7984
}
8085

81-
fn transmit(&'a mut self) -> Option<Self::TxToken> {
86+
fn transmit<'a>(&'a mut self) -> Option<Self::TxToken<'a>> {
8287
let &mut Self {
8388
ref mut inner,
8489
fuzz_rx: _,

src/phy/loopback.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ impl Loopback {
2929
}
3030
}
3131

32-
impl<'a> Device<'a> for Loopback {
33-
type RxToken = RxToken;
34-
type TxToken = TxToken<'a>;
32+
impl Device for Loopback {
33+
type RxToken<'a> = RxToken;
34+
type TxToken<'a> = TxToken<'a>;
3535

3636
fn capabilities(&self) -> DeviceCapabilities {
3737
DeviceCapabilities {
@@ -41,7 +41,7 @@ impl<'a> Device<'a> for Loopback {
4141
}
4242
}
4343

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

54-
fn transmit(&'a mut self) -> Option<Self::TxToken> {
54+
fn transmit<'a>(&'a mut self) -> Option<Self::TxToken<'a>> {
5555
Some(TxToken {
5656
queue: &mut self.queue,
5757
})

src/phy/mod.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct StmPhy {
2929
tx_buffer: [u8; 1536],
3030
}
3131
32-
impl<'a> StmPhy {
32+
impl StmPhy {
3333
fn new() -> StmPhy {
3434
StmPhy {
3535
rx_buffer: [0; 1536],
@@ -38,16 +38,16 @@ impl<'a> StmPhy {
3838
}
3939
}
4040
41-
impl<'a> phy::Device<'a> for StmPhy {
42-
type RxToken = StmPhyRxToken<'a>;
43-
type TxToken = StmPhyTxToken<'a>;
41+
impl phy::Device for StmPhy {
42+
type RxToken<'a> = StmPhyRxToken<'a>;
43+
type TxToken<'a> = StmPhyTxToken<'a>;
4444
45-
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
45+
fn receive<'a>(&'a mut self) -> Option<(Self::RxToken<'a>, Self::TxToken<'a>)> {
4646
Some((StmPhyRxToken(&mut self.rx_buffer[..]),
4747
StmPhyTxToken(&mut self.tx_buffer[..])))
4848
}
4949
50-
fn transmit(&'a mut self) -> Option<Self::TxToken> {
50+
fn transmit<'a>(&'a mut self) -> Option<Self::TxToken<'a>> {
5151
Some(StmPhyTxToken(&mut self.tx_buffer[..]))
5252
}
5353
@@ -308,20 +308,25 @@ impl Default for Medium {
308308
/// The interface is based on _tokens_, which are types that allow to receive/transmit a
309309
/// single packet. The `receive` and `transmit` functions only construct such tokens, the
310310
/// real sending/receiving operation are performed when the tokens are consumed.
311-
pub trait Device<'a> {
312-
type RxToken: RxToken + 'a;
313-
type TxToken: TxToken + 'a;
311+
pub trait Device {
312+
type RxToken<'a>: RxToken
313+
where
314+
Self: 'a;
315+
316+
type TxToken<'a>: TxToken
317+
where
318+
Self: 'a;
314319

315320
/// Construct a token pair consisting of one receive token and one transmit token.
316321
///
317322
/// The additional transmit token makes it possible to generate a reply packet based
318323
/// on the contents of the received packet. For example, this makes it possible to
319324
/// handle arbitrarily large ICMP echo ("ping") requests, where the all received bytes
320325
/// need to be sent back, without heap allocation.
321-
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)>;
326+
fn receive<'a>(&'a mut self) -> Option<(Self::RxToken<'a>, Self::TxToken<'a>)>;
322327

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

326331
/// Get a description of device capabilities.
327332
fn capabilities(&self) -> DeviceCapabilities;

src/phy/pcap_writer.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,15 @@ impl<T: Write> PcapSink for T {
118118
#[derive(Debug)]
119119
pub struct PcapWriter<D, S>
120120
where
121-
D: for<'a> Device<'a>,
121+
D: Device,
122122
S: PcapSink,
123123
{
124124
lower: D,
125125
sink: RefCell<S>,
126126
mode: PcapMode,
127127
}
128128

129-
impl<D: for<'a> Device<'a>, S: PcapSink> PcapWriter<D, S> {
129+
impl<D: Device, S: PcapSink> PcapWriter<D, S> {
130130
/// Creates a packet capture writer.
131131
pub fn new(lower: D, mut sink: S, mode: PcapMode) -> PcapWriter<D, S> {
132132
let medium = lower.capabilities().medium;
@@ -162,19 +162,24 @@ impl<D: for<'a> Device<'a>, S: PcapSink> PcapWriter<D, S> {
162162
}
163163
}
164164

165-
impl<'a, D, S> Device<'a> for PcapWriter<D, S>
165+
impl<D, S> Device for PcapWriter<D, S>
166166
where
167-
D: for<'b> Device<'b>,
168-
S: PcapSink + 'a,
167+
D: Device,
168+
S: PcapSink,
169169
{
170-
type RxToken = RxToken<'a, <D as Device<'a>>::RxToken, S>;
171-
type TxToken = TxToken<'a, <D as Device<'a>>::TxToken, S>;
170+
type RxToken<'a> = RxToken<'a, <D as Device>::RxToken<'a>, S>
171+
where
172+
Self: 'a;
173+
174+
type TxToken<'a> = TxToken<'a, <D as Device>::TxToken<'a>, S>
175+
where
176+
Self: 'a;
172177

173178
fn capabilities(&self) -> DeviceCapabilities {
174179
self.lower.capabilities()
175180
}
176181

177-
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
182+
fn receive<'a>(&'a mut self) -> Option<(Self::RxToken<'a>, Self::TxToken<'a>)> {
178183
let sink = &self.sink;
179184
let mode = self.mode;
180185
self.lower.receive().map(move |(rx_token, tx_token)| {
@@ -192,7 +197,7 @@ where
192197
})
193198
}
194199

195-
fn transmit(&'a mut self) -> Option<Self::TxToken> {
200+
fn transmit<'a>(&'a mut self) -> Option<Self::TxToken<'a>> {
196201
let sink = &self.sink;
197202
let mode = self.mode;
198203
self.lower

0 commit comments

Comments
 (0)