Error: Reached the recursion limit while instantiating `<std::iter::Filter<std::iter::Sk...]>::{closure#0}]>::{closure#0}]>` - recursion

I have a function with following declaration:
fn find_solutions_internal<'a, I>(&self, words: I, iterate_from: usize, chain: &mut Vec<u32>)
where I: Iterator<Item=&'a u32> + Clone;
Because the function recursively iterates over the same vector (max-depth of recursion is 5) with different filters I decided that it would be more effecient to pass the iterator as an argument.
Following part of code causes error:
let iterator = words.skip(iterate_from).filter(|&mask| mask & last_mask == 0);
let filtered_words = iterator.clone();
iterator.enumerate().for_each(|(i, &mask)| {
chain.push(mask);
self.find_solutions_internal(filtered_words.clone(), i, chain); // filtered_words.clone() is what indirectly causes the error
chain.pop();
});
The error:
error: reached the recursion limit while instantiating `<std::iter::Filter<std::iter::Sk...]>::{closure#0}]>::{closure#0}]>`
115 | self.iter.fold(init, fold)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `<std::iter::Filter<I, P> as Iterator>::fold` defined here
...
Self-contained example of the problematic code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ada8578f166ad2a34373d82cc376921f
Working example with collected iteration to vector: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4c13d2d0ac17038dac61c9e2d59bbab5

As #Jmb commented, the compiler does not try figuring out how many times the function recurses, at least not for the purpose of allowing this kind of code to compile. The compiler assumes each call to find_solutions_internal() can potentially recurse, and so the compiler gets stuck repeatedly instantiating the function, as each recursive call has a unique iterator parameter type.
We can fix this problem by passing the iterator as a trait object when making the recursive call, though the fact that we're cloning the iterator complicates things, as the Clone trait doesn't work with trait objects. We can work around that with the dyn_clone crate, at the cost of some boilerplate.
First we define a clonable iterator trait:
use dyn_clone::DynClone;
trait ClonableIterator<T>: Iterator<Item = T> + DynClone {}
impl<I, T> ClonableIterator<T> for I where I: Iterator<Item = T> + DynClone {}
dyn_clone::clone_trait_object!(<T> ClonableIterator<T>);
Then in the recursive call we construct the trait object:
self.find_solutions_internal(
Box::new(filtered_words.clone()) as Box<dyn ClonableIterator<_>>,
i,
chain,
);
While the above solution works, I think it'll likely end up slower than doing the simple thing of just collecting into a Vec. If the vector is really big, using a datastructure like Vector from the im crate, which supports O(1) cloning and O(log n) remove might be faster.

Related

Function with same name as struct

In general, I prefer to write initializer functions with descriptive names. However, for some structs, there is an obvious default initializer function. The standard Rust name for such a function is new, placed in the impl block for the struct. However, today I realized that I can give a function the same name as a struct, and thought this would be a good way to implement the obvious initializer function. For example:
#[derive(Debug, Clone, Copy)]
struct Pair<T, U> {
first: T,
second: U,
}
#[allow(non_snake_case)]
fn Pair<T, U>(first: T, second: U) -> Pair<T, U> {
Pair::<T, U> {
first: first,
second: second,
}
}
fn main(){
let x = Pair(1, 2);
println!("{:?}", x);
}
This is, in my opinion, much more appealing than this:
let x = Pair::new(1, 2);
However, I've never seen anyone else do this, and my question is simply if there are any problems with this approach. Are there, for example, ambiguities which it can cause which will not be there with the new implementation?
If you want to use Pair(T, U) then you should consider using a tuple struct instead:
#[derive(Debug, Clone, Copy)]
struct Pair<T, U>(T, U);
fn main(){
let x = Pair(1, 2);
println!("{:?}", x);
println!("{:?}, {:?}", (x.0, x.1));
}
Or, y’know, just a tuple ((T, U)). But I presume that Pair is not your actual use case.
There was a time when having identically named functions was the convention for default constructors; this convention fell out of favour as time went by. It is considered bad form nowadays, probably mostly for consistency. If you have a tuple struct (or variant) Pair(T, U), then you can use Pair(first, last) in a pattern, but if you have Pair { first: T, last: U } then you would need to use something more like Pair { first, last } in a pattern, and so your Pair(first, last) function would be inconsistent with the pattern. It is generally felt, thus, that these type of camel-case functions should be reserved solely for tuple structs and tuple variants, where it can be known that it is genuinely reflecting what is contained in the data structure with no further processing or magic.

Why is the return type of Deref::deref itself a reference?

I was reading the docs for Rust's Deref trait:
pub trait Deref {
type Target: ?Sized;
fn deref(&self) -> &Self::Target;
}
The type signature for the deref function seems counter-intuitive to me; why is the return type a reference? If references implement this trait so they can be dereferenced, what effect would this have at all?
The only explanation that I can come up with is that references don't implement Deref, but are considered "primitively dereferenceable". However, how would a polymorphic function which would work for any dereferenceable type, including both Deref<T> and &T, be written then?
that references don't implement Deref
You can see all the types that implement Deref, and &T is in that list:
impl<'a, T> Deref for &'a T where T: ?Sized
The non-obvious thing is that there is syntactical sugar being applied when you use the * operator with something that implements Deref. Check out this small example:
use std::ops::Deref;
fn main() {
let s: String = "hello".into();
let _: () = Deref::deref(&s);
let _: () = *s;
}
error[E0308]: mismatched types
--> src/main.rs:5:17
|
5 | let _: () = Deref::deref(&s);
| ^^^^^^^^^^^^^^^^ expected (), found &str
|
= note: expected type `()`
found type `&str`
error[E0308]: mismatched types
--> src/main.rs:6:17
|
6 | let _: () = *s;
| ^^ expected (), found str
|
= note: expected type `()`
found type `str`
The explicit call to deref returns a &str, but the operator * returns a str. It's more like you are calling *Deref::deref(&s), ignoring the implied infinite recursion (see docs).
Xirdus is correct in saying
If deref returned a value, it would either be useless because it would always move out, or have semantics that drastically differ from every other function
Although "useless" is a bit strong; it would still be useful for types that implement Copy.
See also:
Why does asserting on the result of Deref::deref fail with a type mismatch?
Note that all of the above is effectively true for Index and IndexMut as well.
The compiler knows only how to dereference &-pointers - but it also knows that types that implement Deref trait have a deref() method that can be used to get an appropriate reference to something inside given object. If you dereference an object, what you actually do is first obtain the reference and only then dereference it.
If deref() returned a value, it would either be useless because it would always move out, or have semantics that drastically differ from every other function which is not nice.

Multiple mutable borrows when generating a tree structure with a recursive function in Rust

I'm having trouble implementing a recursive function that generates a binary tree by manipulating a mutable list of indices that index into an immutable list.
Here's the code:
enum Tree<'r, T:'r> {
Node(Box<Tree<'r, T>>,
&'r T,
Box<Tree<'r, T>>),
Empty
}
fn process_elements<T>(xs: &mut [T]) {
// interesting things happen here
}
// This function creates a tree of references to elements in a list 'xs' by
// generating a permutation 'indices' of a list of indices into 'xs',
// creating a tree node out of the center element, then recursively building
// the new node's left and right subtrees out of the elements to the left and
// right of the center element.
fn build_tree<'r, T>(xs: &'r [T],
indices: &'r mut [uint]) -> Box<Tree<'r, T>> {
let n = xs.len();
if n == 0 { return box Empty; }
process_elements(indices);
let pivot_index = n / 2;
let left_subtree =
// BORROW 1 ~~~v
build_tree(xs, indices.slice_to_or_fail_mut(&pivot_index));
let right_subtree =
// BORROW 2 ~~~v
build_tree(xs, indices.slice_from_or_fail_mut(&(pivot_index + 1)));
box Node(left_subtree, &xs[pivot_index], right_subtree)
}
When I try to compile this, I get an error saying that I can't borrow *indices as mutable more than once at a time, where the first borrow occurs at the comment marked BORROW 1 and the second borrow occurs at BORROW 2.
I clearly see that *points does get borrowed at both of those locations, but it appears to me that the first borrow of *points should only last until the end of that single recursive call to build_tree in the let left_subtree statement. However, Rust claims that this borrow actually lasts until the end of the entire build_tree function.
Can anyone please explain:
Why the first borrow lasts until the end of the build_tree function, and
How a function like this could be correctly implemented in Rust?
By the way: if I remove the "let left_subtree =" and "let right_subtree =" (i.e., use the recursive calls to build_tree only for their side-effects on indices and pass Nones to the Node constructor), the code compiles just fine and does not complain about multiple borrows. Why is this?
The result of build_tree is Box<Tree<'r, T>>. The borrows extend until the end of the function because the result still borrows from the slice, as evidenced by the lifetime parameter to Tree.
EDIT: The changes below are completely unnecessary in your case. Simply remove 'r from the indices parameter: indices: &mut [uint]. Otherwise, the compiler assumes that you still borrow from the slice because the returned Tree has that lifetime as a parameter. By removing the lifetime on indices, the compiler will infer a distinct lifetime.
To split a mutable slice into two, use split_at_mut. split_at_mut uses unsafe code to work around compiler limitations, but the method itself is not unsafe.
fn build_tree<'r, T>(xs: &'r [T],
indices: &'r mut [uint]) -> Box<Tree<'r, T>> {
let n = xs.len();
if n == 0 { return box Empty; }
process_elements(indices);
let pivot_index = n / 2;
let (indices_left, indices_right) = indices.split_at_mut(pivot_index);
let (_, indices_right) = indices_right.split_at_mut(1);
let left_subtree = build_tree(xs, indices_left);
let right_subtree = build_tree(xs, indices_right);
box Node(left_subtree, &xs[pivot_index], right_subtree)
}

How to rewrite Vec.append "in favor of" extend?

When the following is submitted to the compiler
fn main()
{
let abc = vec![10u, 20u, 30u];
let bcd = vec![20u, 30u, 40u];
let cde = abc.append(bcd.as_slice());
println!("{}", cde);
}
the compiler emits the following warning:
this function has been deprecated in favor of extend()
How would the equivalent look using extend?
Take a look at the signature for extend:
fn extend<I: Iterator<T>>(&mut self, iterator: I)
Note that it takes self by a mutable reference, and that it doesn’t take a slice but rather an iterator (which is more general-purpose).
The end result would look like this, then:
abc.extend(bcd.into_iter());
Or this:
abc.extend(bcd.iter().map(|&i| i))
(Bearing in mind that Vec.iter() produces something that iterates over references rather than values, hence the need for .map(|&i| i).)
I am a little surprised that it is recommending extend, as push_all is a much more direct replacement, taking a slice rather than an iterator:
abc.push_all(bcd.as_slice());

Why can't I reuse a funtion's borrowed pointer

I don't understand why rustc gives me this error error: use of moved value: 'f' at compile time, with the following code:
fn inner(f: &fn(&mut int)) {
let mut a = ~1;
f(a);
}
fn borrow(b: &mut int, f: &fn(&mut int)) {
f(b);
f(b); // can reuse borrowed variable
inner(f); // shouldn't f be borrowed?
// Why can't I reuse the borrowed reference to a function?
// ** error: use of moved value: `f` **
//f(b);
}
fn main() {
let mut a = ~1;
print!("{}", (*a));
borrow(a, |x: &mut int| *x+=1);
print!("{}", (*a));
}
I want to reuse the closure after I pass it as argument to another function. I am not sure if it is a copyable or a stack closure, is there a way to tell?
That snippet was for rustc 0.8. I managed to compile a different version of the code with the latest rustc (master: g67aca9c), changing the &fn(&mut int) to a plain fn(&mut int) and using normal functions instead of a closure, but how can I get this to work with a closure?
The fact of the matter is that &fn is not actually a borrowed pointer in the normal sense. It's a closure type. In master, the function types have been fixed up a lot and the syntax for such things has changed to |&mut int|—if you wanted a borrowed pointer to a function, for the present you need to type it &(fn (...)) (&fn is marked obsolete syntax for now, to help people migrating away from it, because it's a completely distinct type).
But for closures, you can then go passing them around by reference: &|&mut int|.

Resources