Repository navigation
Closed
Labels
F-trait_alias`#![feature(trait_alias)]``#![feature(trait_alias)]`F-type_alias_impl_trait`#[feature(type_alias_impl_trait)]``#[feature(type_alias_impl_trait)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamrequires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
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
F-trait_alias`#![feature(trait_alias)]``#![feature(trait_alias)]`F-type_alias_impl_trait`#[feature(type_alias_impl_trait)]``#[feature(type_alias_impl_trait)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamrequires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
Type
Projects
- StatusShow more project fieldsWontfix
Activity
Aaron1011 commentedon Nov 15, 2019
Minimized:
This appears to be caused by the fact that we create a new inference variable for
FoofromWrapper<Foo>, but never unify it becauseproducedoes not constrain the opaque type.As a side note, we should probably be cheking for type errors when we collect opaque type uses, so that we don't print useless errors like:
wdanilo commentedon Nov 15, 2019
@Aaron1011 thanks for tracking it down. Tbh, I don't see why your code is a minimized version of mine – I don't return from any function variant without the impl trait. This is just a note – I don't know the internals of rustc so I can miss a lot of info here :)
Aaron1011 commentedon Nov 15, 2019
I've opened #66431. It addresses the first 'layer' of errors, but there appear to more (thankfully, better) errors that appear after this one is no longer emitted.
Rollup merge of rust-lang#66431 - Aaron1011:fix/opaque-type-infer, r=…
Rollup merge of rust-lang#66431 - Aaron1011:fix/opaque-type-infer, r=…
Aaron1011 commentedon Jan 9, 2020
This now compiles on the latest nightly.
Aaron1011 commentedon Feb 9, 2020
Actually, this does not compile - I didn't use the modified
_Somefunction when testing.jackh726 commentedon Feb 4, 2021
Errors on current master:
nikomatsakis commentedon Jun 29, 2021
ForI was mistakenmin_type_alias_impl_trait, I believe this is covered by #86732nikomatsakis commentedon Jun 29, 2021
The minimized example (playground:
gives what appears to me to be the correct error:
but the diagnostics are not very good.
nikomatsakis commentedon Jun 29, 2021
In particular, the value of
Foois not constrained at all by this function. If you extend tothen it works.
oli-obk commentedon Sep 9, 2022
The diagnostic for
Playground
is now
oli-obk commentedon Sep 9, 2022
I don't believe there is anything left to do here. Please open a new issue if there are issues beyond the failure to infer the type