rust-bakery/nom

fold parsers still require cloning

djmitche opened this issue · 2 comments

#1354 removed the Clone bounds on R for fold parser, but replaced it with a FnMut bounds on the supplier function. The result is that, if your parser's accumulator begins with a non-empty value that's calculated in advance, you end up having to clone the value anyway:

let initial_value = some_sub_parser(input);
fold_many0(another_sub_parser, move || initial_value.clone(), |acc, item| { .. });

It seems that fold_many0 only calls init once, so it's not clear why this has to be FnMut and not just FnOnce?

Hm, it appears that FnOnce is not possible since this is embedded in the FnMut returned by fold_many*, which may, in fact, be called multiple times in the case of backtracking.

In which case, the Clone bounds was somewhat accurate: this initial value may need to be created multiple times. The supplier function is certainly more flexible! What confused me is that "rewrite init to move || init" isn't quite accurate -- it assumes init is Copy. More accurate is rewrite inittomove || init.clone()`.