-
Notifications
You must be signed in to change notification settings - Fork 96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature reading not reseted between two FeatureIterator instanciation #159
Comments
This is a good catch; I agree we should make the iterator take and store Related to #150 |
Yes, that the first thing that comes to me.
That was my first idea but I'm struggling with Iterator returning object with lifetime from borrowed field from the mutable reference :-p Using
gives:
So I don't know how to make the compiler happy and infer the lifetime for the mutable référence. It seems that requires some magic I do not master atm. The easiest solution would be to stay with a non-mutable reference and stick with the intention note but that's sound unsatisfactory. |
It is a bit more complicated to get it working: we have to store the Also added a test that should fail to compile if un-commented (at the end of fn test_features_mut_lifetime_enforce() {
with_layer("roads.geojson", |mut layer| {
for _ in layer.features() {
let _ = layer.defn();
}
});
} Update: Also added the resetting of iteration, and test to ensure it is being properly reset on creation. |
Nice ! No black magic... If I understand well the layer is borrowed mutably by the iterator because of the inherited lifetime of the
|
Yeah, it is some complicated magic by the compiler. Apparently, even if we down-grade a mut-ref to a immut-ref, it is still considered as a mut-borrow in the scope where the mut borrow happened. See for eg. this playground |
As per the nomicon it is apparently a limitation of the borrow checker. This stackoverflow post explains it well. Interestingly, this "limitation" works out in our favour. We can also make the mut borrow explicit by adding a |
Interesting indeed... Incidentally I have found a working way to cheat with lifetime while keeping a rerence to a mutable layer that also make the job, but it uses some unsafe dark magic: Just for fun:
|
Nice! Note that |
+ add `trybuild` + add test to verify `Layer::features` mut-borrow. Refer georust#159
Between two calls of
Layer::features(&self) -> FeatureIterator
, there is no call toOGR_L_ResetReading
: the consequence is that features cannot be iterated twice from a Layer and the Layer has to be recreated.Ex
As the Layer is not consummed by the iterator and taken from an immutable layer, the internal state should not be changed and it should be possible to get a new iterator over all features.
Since iterating features change the Internal state of a GDAL layer and having two iterator at the same time on the same layer is hazardous, may be the Iterator should be extracted from a mutable layer:
Layer::features(&mut self) -> FeatureIterator
see https://gdal.org/api/vector_c_api.html#_CPPv418OGR_L_ResetReading9OGRLayerH
The text was updated successfully, but these errors were encountered: