Closed
Description
Hi! I'm trying to write a lens library for Rust (see this for reference about lenses: https://github.com/ekmett/lens/wiki). I'm trying to write it in an zero-overhead style, so all lens-usages could be optimized away during compilation stage, thus, I'm trying to create unboxed closures and glue them together. However, a very strange error occurs here. Consider the following code:
#![feature(type_alias_impl_trait)]
#![feature(trait_alias)]
use std::marker::PhantomData;
trait OptGetter<'t,A,B> = Fn(&'t A) -> Option<&'t B>
where A:'t, B:'t, Self:Copy;
struct Lens<'t,Get,A,B>
where Get: OptGetter<'t,A,B> {
get: Get,
phantom: PhantomData<(&'t(),A,B)>
}
type CombinedOptGetter<'t,Get1,Get2,A,B,C> = impl OptGetter<'t,A,C>;
fn combine_opt_getter <'t,Get1,Get2,A,B,C>
(f1: Get1, f2: Get2) -> CombinedOptGetter<'t,Get1,Get2,A,B,C>
where Get1:OptGetter<'t,A,B>,
Get2:OptGetter<'t,B,C> {
move |a| f1(a).and_then(f2)
}
impl<'t,Get,A,B> Lens<'t,Get,A,B>
where Get: OptGetter<'t,A,B> {
pub fn new(get: Get) -> Self {
let phantom = PhantomData;
Self { get, phantom }
}
pub fn combine<Get2, C>(self, that: Lens<'t,Get2,B,C>)
-> Lens<'t,CombinedOptGetter<'t,Get,Get2,A,B,C>,A,C>
where Get2: OptGetter<'t,B,C> {
Lens::new(combine_opt_getter(self.get, that.get))
}
}
trait OptionLens {
type Out;
fn _Some(self) -> Self::Out;
}
type SomeGetter<'t,A> = impl OptGetter<'t,Option<A>,A>;
fn some_getter<'t,A:'t>() -> Lens<'t,SomeGetter<'t,A>,Option<A>,A> {
Lens::new(move|t: &'t Option<A>| t.as_ref())
}
fn _Some<'t, Get, A, B> (this: Lens<'t,Get,A,Option<B>>) -> i32
where Get: OptGetter<'t,A,Option<B>> {
let wrapped: Lens<'t,SomeGetter<'t,B>,Option<B>,B> = some_getter();
let wrapper: Lens<'t,CombinedOptGetter<'t,Get,SomeGetter<'t,B>,A,Option<B>,B>,A,B> = this.combine(wrapped);
7
}
It compiles fine. However, if you try to return wrapper
from the _Some
function, the code will not compile and the errrors we get are not very explanatory either. With this code instead:
fn _Some<'t, Get, A, B> (this: Lens<'t,Get,A,Option<B>>) -> Lens<'t,CombinedOptGetter<'t,Get,SomeGetter<'t,B>,A,Option<B>,B>,A,B>
where Get: OptGetter<'t,A,Option<B>> {
let wrapped: Lens<'t,SomeGetter<'t,B>,Option<B>,B> = some_getter();
let wrapper: Lens<'t,CombinedOptGetter<'t,Get,SomeGetter<'t,B>,A,Option<B>,B>,A,B> = this.combine(wrapped);
wrapper
}
We get:
error[E0283]: type annotations needed: cannot resolve `_: OptGetter<'t, std::option::Option<B>, B>`
--> lib/optics/src/lib.rs:42:1
|
42 | type SomeGetter<'t,A> = impl OptGetter<'t,Option<A>,A>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the return type of a function must have a statically known size
error: concrete type differs from previous defining opaque type use
--> lib/optics/src/lib.rs:47:1
|
47 | / fn _Some<'t, Get, A, B> (this: Lens<'t,Get,A,Option<B>>) -> Lens<'t,CombinedOptGetter<'t,Get,SomeGetter<'t,B>,A,Option<B>,B>,A,B>
48 | | where Get: OptGetter<'t,A,Option<B>> {
49 | | let wrapped: Lens<'t,SomeGetter<'t,B>,Option<B>,B> = some_getter();
50 | | let wrapper: Lens<'t,CombinedOptGetter<'t,Get,SomeGetter<'t,B>,A,Option<B>,B>,A,B> = this.combine(wrapped);
51 | | wrapper
52 | | }
| |_^ expected `[closure@lib/optics/src/lib.rs:44:15: 44:48]`, got `[type error]`
|
note: previous use here
--> lib/optics/src/lib.rs:43:1
|
43 | / fn some_getter<'t,A:'t>() -> Lens<'t,SomeGetter<'t,A>,Option<A>,A> {
44 | | Lens::new(move|t: &'t Option<A>| t.as_ref())
45 | | }
| |_^
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Wontfix