Monday, 15 September 2014

Can you coerce Some(box|:|) to Option<Box<FnOnce>> in rust? -



Can you coerce Some(box|:|) to Option<Box<FnOnce<...>>> in rust? -

as per title. can you? or require intermediary step trait cast?

i realize closure reform isn't done yet, , there number of open bugs it.

however, bug tracker total of bugs , rfcs , links obsolete , new tickets, i'm having hard time trying understand state of play new unboxed closures in rust.

this works:

#![feature(unboxed_closures, unboxed_closure_sugar)] #![allow(dead_code, unused_variables)] fn test(bar:box<fnonce<(int,), ()> + send>) { bar.call_once((10,)); } fn main() { allow bar:box<fnonce<(int,), ()> + send> = box |:x:int| { println!("hi:{}", x); }; test(bar); test(box |:x:int| { println!("hi:{}", x); }); }

and works:

#![feature(unboxed_closures, unboxed_closure_sugar)] #![allow(dead_code, unused_variables)] fn test2(mut bar:option<box<fnonce<(int,), ()> + send>>) { bar.take().unwrap().call_once((10,)); } fn main() { allow bar2:box<fnonce<(int,), ()> + send> = box |:x:int| { println!("hi:{}", x); }; test2(some(bar2)); }

however, doesn't work reason:

#![feature(unboxed_closures, unboxed_closure_sugar)] #![allow(dead_code, unused_variables)] fn test2(mut bar:option<box<fnonce<(int,), ()> + send>>) { bar.take().unwrap().call_once((10,)); } fn main() { test2(some(box |:x:int| { println!("hi:{}", x); })); }

error:

foo.rs:21:9: 21:53 error: mismatched types: expected `core::option::option<box<core::ops::fnonce<(int,), ()>+send>>`, found `core::option::option<box<closure>>` (expected trait core::ops::fnonce, found closure) foo.rs:21 test2(some(box |:x:int| { println!("hi:{}", x); }));

so, question:

1) should above code work? or option<>/some() imply complex haven't understood in context?

2) if so, there open ticket implicit conversions between |:| sugar , fnonce types?

(because https://github.com/rust-lang/rust/issues/18101 seems suggest should done, why illustration #1 works, i've gotten lost trying hunt through meta bug find specific bug referring closure sugar).

it worth noting general property of trait objects , generic structs/enums, , not @ specific unboxed closures, fnonce, option or |:| (especially not this, since nice way create value implementing trait).

also, recent rfc #401 related.

1) should above code work? or option<>/some() imply complex haven't understood in context?

box<fnonce<..>> trait object , not have same representation or type non-dynamic box<f> f: fnonce<...>. theoretically back upwards fancier deep coercions through enums , structs types, wouldn't play well/uniformly co- , contra-variance.

in case, can normal trait object cast:

#![feature(unboxed_closures, unboxed_closure_sugar)] #![allow(dead_code, unused_variables)] fn test2(mut bar:option<box<fnonce<(int,), ()> + send>>) { bar.take().unwrap().call_once((10,)); } fn main() { test2(some((box |: x| println!("hi:{}", x)) box<fnonce(int)+send>)); }

on note variance, consider:

enum option2<t> { empty, one(fn() -> t) }

that is, either stores nil or stores function returns t. mean cast option2<box<x>> option2<box<trait>>? 1 cannot forcibly pretend function returning box<x> returns value of type box<trait>.

2) if so, there open ticket implicit conversions between |:| sugar , fnonce types?

the |:| sugar fnonce-implementing type. fnonce trait , coercions happen other trait object.

rust

No comments:

Post a Comment