Skip to content

Commit e6fbc13

Browse files
core: Relax lifetime constraint on msgs in I2CTransfer::transfer()
This change enables users of `i2cdev` to create generic functions on `T: I2CTransfer` that have output buffers constructed separately from the `I2CMessage` array, like the following: ```rust fn smbus_read_post_box<T>(i2c: &mut T, offset: u16, out: &mut [u8]) where for<'a> T: I2CTransfer<'a>, { let addr = offset.to_be_bytes(); let mut messages = [ T::Message::write(addr), T::Message::read(out), ]; i2c.transfer(&mut messages).expect("uh oh"); } ``` Before this, `messages` would not satisfy the constraints of `.transfer()`, because `messages` does not live as long as one of the output buffers `out`: ``` error[E0597]: `messages` does not live long enough --> src/smbpbisensor.rs:69:19 | 63 | let mut messages = [ | ------------ binding `messages` declared here ... 69 | .transfer(&mut messages) | ^^^^^^^^^^^^^ borrowed value does not live long enough ... 78 | } | - | | | `messages` dropped here while still borrowed | borrow might be used here, when `messages` is dropped and runs the destructor for type `[<T as I2CTransfer<'_>>::Message; 2]` ``` The error message is a little confusing, but basically `&'a mut [Self::Message]` is forcing the array of `I2CMessage`s to match the lifetime of the buffers in the messages, which is not strictly necessary: the array of messages can have a different lifetime than the buffers. After this change, the above example compiles successfully.
1 parent c88553a commit e6fbc13

File tree

4 files changed

+6
-4
lines changed

4 files changed

+6
-4
lines changed

Diff for: CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Versioning](https://semver.org/spec/v2.0.0.html).
88

99
## [Unreleased]
1010

11+
- Relax lifetime constraint on `I2CTransfer::transfer` `msgs` reference
12+
1113
## [v0.6.1] - 2024-05-09
1214

1315
- Properly ellide the start bit when sending a series of I2C messages as a

Diff for: src/core.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ pub trait I2CTransfer<'a> {
137137
/// Performs multiple serially chained I2C read/write transactions. On
138138
/// success the return code is the number of successfully executed
139139
/// transactions
140-
fn transfer(&mut self, msgs: &'a mut [Self::Message]) -> Result<u32, Self::Error>;
140+
fn transfer(&mut self, msgs: &mut [Self::Message]) -> Result<u32, Self::Error>;
141141
}
142142

143143
/// Read/Write I2C message

Diff for: src/linux.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ impl<'a> I2CTransfer<'a> for LinuxI2CDevice {
299299
type Message = LinuxI2CMessage<'a>;
300300

301301
/// Issue the provided sequence of I2C transactions
302-
fn transfer(&mut self, messages: &'a mut [Self::Message]) -> Result<u32, LinuxI2CError> {
302+
fn transfer(&mut self, messages: &mut [Self::Message]) -> Result<u32, LinuxI2CError> {
303303
let msg_type = |flag: u16| flag & I2CMessageFlags::READ.bits();
304304
let mut prev_msg_type = None;
305305
for msg in messages.iter_mut() {
@@ -335,7 +335,7 @@ impl<'a> I2CTransfer<'a> for LinuxI2CBus {
335335
type Message = LinuxI2CMessage<'a>;
336336

337337
/// Issue the provided sequence of I2C transactions
338-
fn transfer(&mut self, msgs: &'a mut [Self::Message]) -> Result<u32, LinuxI2CError> {
338+
fn transfer(&mut self, msgs: &mut [Self::Message]) -> Result<u32, LinuxI2CError> {
339339
ffi::i2c_rdwr(self.as_raw_fd(), msgs).map_err(From::from)
340340
}
341341
}

Diff for: src/mock.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ where
152152
type Message = MockI2CMessage<'a>;
153153

154154
/// Issue the provided sequence of I2C transactions
155-
fn transfer(&mut self, messages: &'a mut [Self::Message]) -> Result<u32, Self::Error> {
155+
fn transfer(&mut self, messages: &mut [Self::Message]) -> Result<u32, Self::Error> {
156156
for msg in messages.iter_mut() {
157157
match &mut msg.msg_type {
158158
MessageType::Read(data) => self.read(data)?,

0 commit comments

Comments
 (0)