Implement a trait for both Iter<&> and Iter<&mut> [duplicate] - rust

This question already has answers here:
Conflicting trait implementations even though associated types differ
(2 answers)
Closed 9 months ago.
I am trying to write a conversion trait that can take both Iterators to references and Iterators to mutable references.
Sadly, it seems that once you implement a trait for Iter<&>, you cannot implement the trait also for Iter<&mut> as they seem to collide. Which doesn't make sense, though, because Iter<&mut> doesn't seem to be able to utilize the implementation for Iter<&>.
Here is a minimal example:
// A dummy object
#[derive(Debug)]
struct MyObj(i32);
// A collection of MyObj references
#[derive(Debug)]
struct RefVec<'a>(Vec<&'a MyObj>);
// Goal: create a conversion function that can take *either* a `Iterator<&MyObj>` *or* `Iterator<&mut MyObj>`.
// Attempt: Create a Conversion Trait and implement it for both of those types
trait ConvertToRefVec<'a> {
fn convert(&mut self) -> RefVec<'a>;
}
// Implement the conversion for Iter<&MyObj>
impl<'a, T> ConvertToRefVec<'a> for T
where
T: Iterator<Item = &'a MyObj>,
{
fn convert(&mut self) -> RefVec<'a> {
RefVec(self.collect::<Vec<_>>())
}
}
// Problem: the impl above does not apply to Iter<&mut MyObj>. But the attempt to write an impl
// for Iter<&mut MyObj> fails with the message that it collides with the impl above:
impl<'a, T> ConvertToRefVec<'a> for T
where
T: Iterator<Item = &'a mut MyObj>,
{
fn convert(&mut self) -> RefVec<'a> {
RefVec(self.collect::<Vec<_>>())
}
}
fn main() {
let owned = [MyObj(42), MyObj(69)];
let ref_vec = owned.iter().convert();
println!("{:?}", ref_vec);
let ref_vec = owned.iter_mut().convert();
println!("{:?}", ref_vec);
}
Which gives me:
error[E0119]: conflicting implementations of trait `ConvertToRefVec<'_>`
--> src/main.rs:27:1
|
16 | / impl<'a, T> ConvertToRefVec<'a> for T
17 | | where
18 | | T: Iterator<Item = &'a MyObj>,
19 | | {
... |
22 | | }
23 | | }
| |_- first implementation here
...
27 | / impl<'a, T> ConvertToRefVec<'a> for T
28 | | where
29 | | T: Iterator<Item = &'a mut MyObj>,
30 | | {
... |
33 | | }
34 | | }
| |_^ conflicting implementation
But if I leave out the impl for Iterator<&mut>, then I get this error:
error[E0599]: the method `convert` exists for struct `std::slice::IterMut<'_, MyObj>`, but its trait bounds were not satisfied
--> src/main.rs:42:36
|
42 | let ref_vec = owned.iter_mut().convert();
| ^^^^^^^ method cannot be called on `std::slice::IterMut<'_, MyObj>` due to unsatisfied trait bounds
|
::: /home/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/iter.rs:187:1
|
187 | pub struct IterMut<'a, T: 'a> {
| -----------------------------
| |
| doesn't satisfy `<_ as Iterator>::Item = &MyObj`
| doesn't satisfy `std::slice::IterMut<'_, MyObj>: ConvertToRefVec`
|
note: trait bound `<std::slice::IterMut<'_, MyObj> as Iterator>::Item = &MyObj` was not satisfied
--> src/main.rs:18:17
|
16 | impl<'a, T> ConvertToRefVec<'a> for T
| ------------------- -
17 | where
18 | T: Iterator<Item = &'a MyObj>,
| ^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here
So my question is: How can I write such a conversion mechanism that works with both Iterator<Item = &MyObj> and Iterator<Item = &mut MyObj?

The thing is that you are trying to implement your trait in two different ways for the same type. So the problem that you treat T as the same one. Then you can just split the cases for concrete types. Like to following:
#[derive(Debug)]
struct MyObj(i32);
#[derive(Debug)]
struct RefVec<'a>(Vec<&'a MyObj>);
trait ConvertToRefVec<'a> {
fn convert(&mut self) -> RefVec<'a>;
}
impl<'a> ConvertToRefVec<'a> for std::slice::Iter<'a, MyObj>
{
fn convert(&mut self) -> RefVec<'a> {
RefVec(self.collect::<Vec<_>>())
}
}
impl<'a> ConvertToRefVec<'a> for std::slice::IterMut<'a, MyObj>
{
fn convert(&mut self) -> RefVec<'a> {
RefVec(self.map(|el| &*el).collect::<Vec<&MyObj>>())
}
}
fn main() {
let mut owned = [MyObj(42), MyObj(69)];
let ref_vec = owned.iter().convert();
println!("{:?}", ref_vec);
let ref_vec = owned.iter_mut().convert();
println!("{:?}", ref_vec);
}

Related

conflicting lifetime requirements on implementing Clone for simple struct

I'm designing a simple type to hold either a Vec<u8> or a slice (mut or not mut). I'm having problems on lifetime constraints and this time I don't know why there are conflicting requirements:
use std::vec::Vec;
pub enum EncodedPacket<'a> {
Owned(Vec<u8>),
Ref(&'a [u8]),
RefMut(&'a mut [u8])
}
impl<'a> EncodedPacket<'a> {
pub fn new_ref(slice: &'a [u8]) -> EncodedPacket<'a> {
EncodedPacket::Ref(slice)
}
pub fn new_ref_mut(slice: &'a mut [u8]) -> EncodedPacket<'a> {
EncodedPacket::RefMut(slice)
}
pub fn new_owned(vec: Vec<u8>) -> EncodedPacket<'a> {
EncodedPacket::Owned(vec)
}
}
impl<'a> Clone for EncodedPacket<'a> {
fn clone(&self) -> Self {
match self {
EncodedPacket::Owned(vec)=> EncodedPacket::new_owned(*vec),
EncodedPacket::Ref(slice) => EncodedPacket::new_ref(*slice),
EncodedPacket::RefMut(slice) => EncodedPacket::new_ref_mut(*slice)
}
}
}
Playground
Error:
Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime for pattern due to conflicting requirements
--> src/lib.rs:28:35
|
28 | EncodedPacket::RefMut(slice) => EncodedPacket::new_ref_mut(*slice)
| ^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 24:14...
--> src/lib.rs:24:14
|
24 | fn clone(&self) -> Self {
| ^^^^^
note: ...so that reference does not outlive borrowed content
--> src/lib.rs:28:35
|
28 | EncodedPacket::RefMut(slice) => EncodedPacket::new_ref_mut(*slice)
| ^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 23:6...
--> src/lib.rs:23:6
|
23 | impl<'a> Clone for EncodedPacket<'a> {
| ^^
note: ...so that the expression is assignable
--> src/lib.rs:25:9
|
25 | / match self {
26 | | EncodedPacket::Owned(vec)=> EncodedPacket::new_owned(*vec),
27 | | EncodedPacket::Ref(slice) => EncodedPacket::new_ref(*slice),
28 | | EncodedPacket::RefMut(slice) => EncodedPacket::new_ref_mut(*slice)
29 | | }
| |_________^
= note: expected `EncodedPacket<'a>`
found `EncodedPacket<'_>`
I'm just recreating EncodedPacket with the same internal things, I don't see why there are conflicting lifetime requirements at all.
You cannot clone a mutable reference. One way of doing this would be to wrap it in Rc and Rc<RefCell>:
use std::vec::Vec;
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Clone)]
pub enum EncodedPacket<'a> {
Owned(Vec<u8>),
Ref(Rc<&'a [u8]>),
RefMut(Rc<RefCell<&'a mut [u8]>>)
}
impl<'a> EncodedPacket<'a> {
pub fn new_ref(slice: &'a [u8]) -> EncodedPacket<'a> {
EncodedPacket::Ref(Rc::new(slice))
}
pub fn new_ref_mut(slice: &'a mut [u8]) -> EncodedPacket<'a> {
EncodedPacket::RefMut(Rc::new(RefCell::new(slice)))
}
pub fn new_owned(vec: Vec<u8>) -> EncodedPacket<'a> {
EncodedPacket::Owned(vec)
}
}
Playground

Problem with lifetimes and implementing Clone

I'm trying to define a struct representing a function that can be composed using different arithmetic operations (only addition has been implemented).
I would like to implement Clone for my struct, however I can't seem to it to work:
use std::ops::Add;
use std::boxed::Box;
use std::clone::Clone;
type InputT = i32;
type OutputT = f64;
pub struct ComposableFn<'a> {
f: Box<dyn 'a + Fn(InputT) -> OutputT>,
}
impl<'a> ComposableFn<'a> {
pub fn new<F: 'a + Fn(InputT) -> OutputT>(f: F) -> Self {
Self {
f: Box::new(f)
}
}
pub fn compute(&self, x: InputT) -> OutputT {
(self.f)(x)
}
}
impl<'a> Add<&'a ComposableFn<'a>> for &'a ComposableFn<'a> {
type Output = ComposableFn<'a>;
fn add(self, rhs: &'a ComposableFn) -> Self::Output {
ComposableFn::new(move |x| self.compute(x) + rhs.compute(x))
}
}
impl<'a> Clone for ComposableFn<'a> {
fn clone(&'a self) -> Self {
ComposableFn::new(move |x| self.compute(x))
}
}
fn main() {
let id = ComposableFn::new(|x| x.into());
println!("{}", id.compute(12));
let double = &id + &id;
println!("{}", double.compute(7));
let triple = &double + &id;
println!("{}", triple.compute(3));
}
When compiling I get the following error:
error[E0308]: method not compatible with trait
--> src/main.rs:33:5
|
33 | fn clone(&'a self) -> Self {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected fn pointer `fn(&ComposableFn<'a>) -> ComposableFn<'_>`
found fn pointer `fn(&'a ComposableFn<'a>) -> ComposableFn<'_>`
note: the anonymous lifetime #1 defined on the method body at 33:5...
--> src/main.rs:33:5
|
33 | fn clone(&'a self) -> Self {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 32:6
--> src/main.rs:32:6
|
32 | impl<'a> Clone for ComposableFn<'a> {
| ^^
error: aborting due to previous error
Removing the 'a from fn clone(&'a self) results in the following error instead:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/main.rs:34:27
|
34 | ComposableFn::new(move |x| self.compute(x))
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 33:5...
--> src/main.rs:33:5
|
33 | fn clone(&self) -> Self {
| ^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that the types are compatible
--> src/main.rs:34:27
|
34 | ComposableFn::new(move |x| self.compute(x))
| ^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `&ComposableFn<'_>`
found `&ComposableFn<'a>`
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 32:6...
--> src/main.rs:32:6
|
32 | impl<'a> Clone for ComposableFn<'a> {
| ^^
note: ...so that the expression is assignable
--> src/main.rs:34:9
|
34 | ComposableFn::new(move |x| self.compute(x))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `ComposableFn<'a>`
found `ComposableFn<'_>`
error: aborting due to previous error
Is there a way to fix this?
You cannot implement Clone this way. Clone requires the return type to match exactly, which means the exact same lifetime 'a. But you're trying to make a clone that references self which has a different lifetime.
The straightforward solution would be to just clone f. Unfortunately, you can't clone a Box<dyn...>, at least not without some help. See: How to clone a struct storing a boxed trait object?
The only direct solution would be to swap Box out with Rc so they share ownership:
use std::rc::Rc;
pub struct ComposableFn<'a> {
f: Rc<dyn 'a + Fn(InputT) -> OutputT>,
}
impl Clone for ComposableFn<'_> {
fn clone(&self) -> Self {
ComposableFn { f: self.f.clone() }
}
}

In Rust, how do I create a mutable iterator? [duplicate]

This question already has answers here:
How can I create my own data structure with an iterator that returns mutable references?
(1 answer)
How to implement Iterator yielding mutable references [duplicate]
(2 answers)
Closed 2 years ago.
I'm having difficulty with lifetimes when trying to create a mutable iterator in safe Rust.
Here is what I have reduced my problem to:
struct DataStruct<T> {
inner: Box<[T]>,
}
pub struct IterMut<'a, T> {
obj: &'a mut DataStruct<T>,
cursor: usize,
}
impl<T> DataStruct<T> {
fn iter_mut(&mut self) -> IterMut<T> {
IterMut { obj: self, cursor: 0 }
}
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
let i = f(self.cursor);
self.cursor += 1;
self.obj.inner.get_mut(i)
}
}
fn f(i: usize) -> usize {
// some permutation of i
}
The structure of my DataStruct will never change, but I need to be able to mutate the contents of the elements stored within. For example,
let mut ds = DataStruct{ inner: vec![1,2,3].into_boxed_slice() };
for x in ds {
*x += 1;
}
The compiler is giving me an error about conflicting lifetimes for the reference I am trying to return. The lifetime it finds that I am not expecting is the scope of the next(&mut self) function.
If I try to annotate the lifetime on next(), then the compiler, instead, tells me I haven't satisfied the Iterator trait. Is this solvable in safe rust?
Here is the error:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/iter_mut.rs:25:24
|
25 | self.obj.inner.get_mut(i)
| ^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 22:5...
--> src/iter_mut.rs:22:5
|
22 | / fn next(&mut self) -> Option<Self::Item> {
23 | | let i = self.cursor;
24 | | self.cursor += 1;
25 | | self.obj.inner.get_mut(i)
26 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/iter_mut.rs:25:9
|
25 | self.obj.inner.get_mut(i)
| ^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 19:6...
--> src/iter_mut.rs:19:6
|
19 | impl<'a, T> Iterator for IterMut<'a, T> {
| ^^
note: ...so that the types are compatible
--> src/iter_mut.rs:22:46
|
22 | fn next(&mut self) -> Option<Self::Item> {
| ______________________________________________^
23 | | let i = self.cursor;
24 | | self.cursor += 1;
25 | | self.obj.inner.get_mut(i)
26 | | }
| |_____^
= note: expected `std::iter::Iterator`
found `std::iter::Iterator`
edits:
changed implementation of next() so that iteration order is a permutation of original sequence.
The borrow checker is unable to prove that subsequent calls to next() won't access the same data. The reason why this is a problem is because the lifetime of the borrow is for the duration of the life of the iterator, so it can't prove that there won't be two mutable references to the same data at the same time.
There really isn't a way to solve this without unsafe code - or changing your data structures. You could do the equlivant of slice::split_at_mut but, given that you can't mutate the original data, you'd have to implement that in unsafe code anyway. An unsafe implementation could look something like this:
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
let i = self.cursor;
self.cursor += 1;
if i < self.obj.inner.len() {
let ptr = self.obj.inner.as_mut_ptr();
unsafe {
Some(&mut *ptr.add(i))
}
} else {
None
}
}
}

How do I create a tokio specialized transport to override the default tick implementation?

I'm attempting to write a streaming, pipelined server with a non-default tick() method in the transport. I thought this would do it:
use std::io;
use mio::net::TcpListener;
use tokio_core::reactor::PollEvented;
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_io::codec::{Framed, Encoder, Decoder};
use tokio_proto::streaming::pipeline::Transport;
use codec::PacketCodec;
type GearmanIO = PollEvented<TcpListener>;
type GearmanFramed = Framed<GearmanIO, PacketCodec>;
impl Transport for GearmanFramed {
fn tick(&mut self) {
trace!("tick!");
}
fn cancel(&mut self) -> io::Result<()> {
trace!("cancel!");
}
}
But, trying to build this file yields this:
error[E0119]: conflicting implementations of trait `tokio_proto::streaming::pipeline::Transport` for type `tokio_io::codec::Framed<tokio_core::reactor::PollEvented<mio::net::TcpListener>, codec::PacketCodec>`:
--> src/transport.rs:14:1
|
14 | / impl Transport for GearmanFramed
15 | | {
16 | | fn tick(&mut self) {
17 | | trace!("tick!");
... |
22 | | }
23 | | }
| |_^
|
= note: conflicting implementation in crate `tokio_proto`
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> src/transport.rs:14:1
|
14 | / impl Transport for GearmanFramed
15 | | {
16 | | fn tick(&mut self) {
17 | | trace!("tick!");
... |
22 | | }
23 | | }
| |_^ impl doesn't use types inside crate
|
= note: the impl does not reference any types defined in this crate
= note: define and implement a trait or new type instead
I would have expected that the specific nature of GearmanFramed would allow me to implement the Transport trait due to "specialization", but this one is still conflicting with the default, which is here:
use tokio_io as new_io;
// ...
impl<T, C> Transport for new_io::codec::Framed<T,C>
where T: new_io::AsyncRead + new_io::AsyncWrite + 'static,
C: new_io::codec::Encoder<Error=io::Error> +
new_io::codec::Decoder<Error=io::Error> + 'static,
{}
So after a few days of struggling, I figured this out. The answer is to use a newtype to surround Framed, thus avoiding the default implementation.
use std::io;
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_io::codec::{Framed, Encoder, Decoder};
use tokio_proto::streaming::pipeline::Transport;
use futures::{Poll, Sink, StartSend, Stream};
use codec::PacketCodec;
pub struct GearmanFramed<T>(pub Framed<T, PacketCodec>);
impl<T> Transport for GearmanFramed<T>
where T: AsyncRead + AsyncWrite + 'static
{
fn tick(&mut self) {
trace!("tick!");
}
fn cancel(&mut self) -> io::Result<()> {
trace!("cancel!");
Ok(())
}
}
impl<T> Stream for GearmanFramed<T>
where T: AsyncRead
{
type Item = <PacketCodec as Decoder>::Item;
type Error = <PacketCodec as Decoder>::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
self.0.poll()
}
}
impl<T> Sink for GearmanFramed<T>
where T: AsyncWrite
{
type SinkItem = <PacketCodec as Encoder>::Item;
type SinkError = <PacketCodec as Encoder>::Error;
fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
self.0.start_send(item)
}
fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
self.0.poll_complete()
}
fn close(&mut self) -> Poll<(), Self::SinkError> {
self.0.close()
}
}

Cannot infer appropriate lifetime for autoref when calling a method from an Iterator implementation

I am trying to implement the Iterator trait for a struct which acts as a borrower of an array of i32 values, but I keep running into the compiler complaining about not being able to infer a lifetime inside the next method.
I am aware of Need help understanding Iterator lifetimes, but since my struct just borrows a slice of the array anyway, I keep the memory of the actual elements separate from my IntegerArrayBag.
#[derive(Debug)]
struct IntegerArrayBag<'a> {
arr: &'a [i32],
idx: usize,
}
impl<'a> IntegerArrayBag<'a> {
fn len(&self) -> usize {
self.arr.len()
}
fn get(&self, idx: usize) -> Option<&i32> {
if self.arr.len() > idx {
Some(&self.arr[idx])
} else {
None
}
}
}
impl<'a> Iterator for IntegerArrayBag<'a> {
type Item = &'a i32;
fn next(&mut self) -> Option<&'a i32> {
let idx = self.idx;
self.idx += 1;
self.get(idx)
}
}
If I try to compile this code, the compiler complains with:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/main.rs:27:14
|
27 | self.get(idx)
| ^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 24:5...
--> src/main.rs:24:5
|
24 | / fn next(&mut self) -> Option<&'a i32> {
25 | | let idx = self.idx;
26 | | self.idx += 1;
27 | | self.get(idx)
28 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:27:9
|
27 | self.get(idx)
| ^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 21:1...
--> src/main.rs:21:1
|
21 | / impl<'a> Iterator for IntegerArrayBag<'a> {
22 | | type Item = &'a i32;
23 | |
24 | | fn next(&mut self) -> Option<&'a i32> {
... |
28 | | }
29 | | }
| |_^
note: ...so that expression is assignable (expected std::option::Option<&'a i32>, found std::option::Option<&i32>)
--> src/main.rs:27:9
|
27 | self.get(idx)
| ^^^^^^^^^^^^^
You need to update your get method to return a reference with longer life:
// Use 'a from impl<'a> IntegerArrayBag<'a>
fn get(&self, idx: usize) -> Option<&'a i32> {
and then it will compile.
Changing get(…) to return Option<&'a i32> makes it compile.
Playground URL: https://play.rust-lang.org/?gist=10783e90287b7111c126&version=stable
Gist URL: https://gist.github.com/10783e90287b7111c126

Resources