rust


Caught between a lifetime and an FFI place


I am caught between two different issues/bugs, and can't come up with a decent solution. Any help would be greatly appreciated
Context, FFI, and calling a lot of C functions, and wrapping C types in rust structs.
The first problem is ICE: this path should not cause illegal move.
This is forcing me to do all my struct-wrapping using & references as in:
pub struct CassResult<'a> {
result:&'a cql_ffi::CassResult
}
Instead of the simpler, and preferable:
pub struct CassResult {
result:cql_ffi::CassResult
}
Otherwise code like:
pub fn first_row(&self) -> Result<CassRow,CassError> {unsafe{
Ok(CassRow{row:*cql_ffi::cass_result_first_row(self.result)})
}}
Will result in:
error: internal compiler error: this path should not cause illegal move
Ok(CassRow{row:*cql_ffi::cass_result_first_row(self.result)})
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
So, I go ahead and wrap everything using lifetime managed references, and all is not-horrible until I try to implement an iterator. At which point I see no way around this problem.
method next has an incompatible type for trait: expected concrete lifetime, found bound lifetime parameter
So given those two conflicting issues, I am totally stuck and can't find any way to implement a proper rust iterator around a FFI iterator-like construct.
Edit: With Shep's suggestion, I get:
pub struct CassResult {
pub result:cql_ffi::CassResult
}
and
pub fn get_result(&mut future:future) -> Option<CassResult> {unsafe{
let result:&cql_ffi::CassResult = &*cql_ffi::cass_future_get_result(&mut future.future);
Some(CassResult{result:*result})
}}
but then get:
error: cannot move out of borrowed content
Some(CassResult{result:*result}
Is there any way to make that pattern work? It's repeated all over this FFI wrapping code.
Only a partial answer: use the "streaming iterator" trait and macro.
I have had a similar problem making Rust bindings around the C mysql API. The result is code like this, instead of native for syntax:
let query = format!("SELECT id_y, value FROM table_x WHERE id = {}", id_x);
let res = try!(db::run_query(&query));
streaming_for!( row, res.into_iter(), {
let id_y: usize = try!(row.convert::<usize>(0));
let value: f64 = try!(row.convert::<f64>(1));
});
Here res holds the result and frees memory on drop. The lifetime of row is tied to res:
/// Res has an attached lifetime to guard an internal pointer.
struct Res<'a>{ p: *mut c_void }
/// Wrapper created by into_iter()
struct ResMoveIter<'a>{ res: Res<'a> }
impl<'a> /*StreamingIterator<'a, Row<'a>> for*/ ResMoveIter<'a>{
/// Get the next row, or None if no more rows
pub fn next(&'a mut self) -> Option<Row<'a>>{
...
}
}
#[unsafe_destructor]
impl<'a> Drop for Res<'a>{
fn drop(&mut self){
...
}
}
To answer my own question. The only decent answer was a way around the original ICE, but as thepowersgang comments, the correct way to do this now is to use :std::ptr::read, so using that approach, no ICE, and hopefully progress.

Related Links

Is it possible to deactivate file locking in cargo?
“does not live long enough” error in same function
What ways exist to create containers of several types? [duplicate]
How can I optimize reading a UTF-8 string from a file with a known offset and size?
Create vector of objects implementing a trait in Rust
Using loop variable from “..” loop causes type conversion?
What is RFC 401's coerce_inner useful for?
Rust Borrow checker only complains about borrowing as mutable multiple times when a function that returns a reference with the same lifetime assigned
How can I remove `let _ : () = …`?
Does if-let with a pair short-circuit?
Rust borrow lasts beyond the scope it's in?
How can I include an arbitrary set of Protobuf-built files without knowing their names?
Specialization of method in inherent impl
Getting reference to object behind Rc
Similar implementations of one trait for many structs
Unable to find unsafe trait implementation

Categories

HOME
office365
windows-8.1
vagrant
eclipse-plugin
bokeh
kendo-dropdown
redmine
kivy
odata
typeerror
tfs2015
bittorrent
facebook-android-sdk
pyresttest
selection
stack-overflow
lc3
sap-fiori
multi-step
sslhandshakeexception
jquery-file-upload
stimulsoft
bundler
google-cloud-logging
tomcat8
gmp
wsf
pe
yii2-basic-app
backtracking
dragula
web-push
pubxml
code-climate
locks
dotcms
wampsharp
jfxtras
textmate2
grails3.2.0
windows-media-player
.net-micro-framework
nothing
brightscript
watir-webdriver
android-mediarecorder
portability
emacs25
word-2016
http4s
xmlbeans
dpkg
rails-engines
maximize
android-async-http
vimperator
largenumber
gluon-desktop
css-paged-media
wicked-gem
web-api
text-align
mathematical-expressions
tidyr
nhibernate-criteria
nanomsg
famo.us
dnsjava
mobile-country-code
libgcc
xcode6.3.1
screwturn
redpitaya
hyperloglog
sensormanager
progress-db
notifyjs
disjoint-union
tfs-sdk
jquery-cycle
dojo-1.9
daap
clearinterval
popup-blocker
arrow
sfinae
viewpagerindicator
autosize
nosetests
ios-4.2
3-tier
oracle-pro-c
dm
objectinstantiation

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App