So I have a pair of trait methods that both return iterators over u32, but different kinds of iterators. I want the user to see both as basically one kind of iterator. I have this:
Surround your code snippets with 3 backticks to get proper formatting. Also, it's much easier for people to help if you put a minimal example of your code in the playground: https://play.rust-lang.org/
With that out of the way, it's hard to say for sure how you should define your types because you've not shown enough code (e.g. what does MyType look like and how will it return the BasicIter type?).
You may need to add a generic lifetime parameter to MyTrait so it would look like:
pub trait MyTrait<'a> {
type MyIter: Iterator<Item = u_nf>;
fn iter(&'a self) -> Self::MyIter;
}
impl<'a, T> MyTrait<'a> for MyType {
type MyIter = BasicIter<'a>; // Why is this associated type called NI in your example?
// Then presumably something like this, where BasicIter could borrow from `self`
fn iter(&'a self) -> Self::MyIter { ... }
}
If you show more code, maybe we'll come up with something (if the above doesn't help).
I guess I don't have a good mental model about what happens to lifetimes when mixed into trait definitions and impl<..> clauses.
I understand lifetimes for function definitions. That says, "When I call this function with these parameters, make sure the references I return last at least as long as these things I provided."
That's easy to understand.
Something like this:
pub trait BackingItems<'a> {
type A : 'a + Item;
type ItemIterator : Iterator<Item=&'a Self::A>;
fn underlying_items(&'a self) -> Self::ArcIterator;
}
impl<'a, A : Arc> BackingItems<'a> for BasicObject<A> where A : 'a {
type A = A;
type ItemIter = slice::Iter<'a, A>;
fn underlying_items(&'a self) -> Self::ItemIter {
self.items.iter()
}
I don't see how that lifetime ('a) relates to the actually call flow of my code.
I get putting the 'a into the Iterator<Item=&'A>. I also get putting it into the parameter of underlying_times. That's just the normal case: function call and returned type. But why do I need the where A : 'a clause?
Since you’re indicating that you have &'a A yielded by the ItemIterator, the compiler wants you to explicitly indicate that A is going to be valid for that lifetime 'a. This ensures that the reference doesn’t outlive the referenced content.
I believe this constraint is going to be unnecessary in Rust 2018 (ie it’ll be implied in cases like this and doesn’t need to be stated manually).