Skip to content
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

Generic fn cannot be converted to for<'a> Fn #22791

Closed
theemathas opened this issue Feb 25, 2015 · 7 comments
Closed

Generic fn cannot be converted to for<'a> Fn #22791

theemathas opened this issue Feb 25, 2015 · 7 comments
Labels
A-typesystem Area: The type system

Comments

@theemathas
Copy link

This code causes a compile error, but I think that it should compile without problems.

use std::marker::PhantomFn;

struct Foo(Bar);
struct Bar;

trait BorrowFn<'a>: PhantomFn<&'a Self, ()> {}
impl<'a, T: 'a, F: Fn(&'a Foo) -> T> BorrowFn<'a> for F {}

fn something<F>(_: F) where for<'a> F: BorrowFn<'a> {}

fn foo_as_bar<'a>(x: &'a Foo) -> &'a Bar { &x.0 }

fn main() {
    something(foo_as_bar);
}

playpen

The compile errors:

<anon>:14:5: 14:14 error: the requirement `for<'a> _ : 'a` is not satisfied [E0280]
<anon>:14     something(foo_as_bar);
              ^~~~~~~~~
<anon>:14:5: 14:14 error: type mismatch resolving `for<'a> <fn(&'a Foo) -> &'a Bar {foo_as_bar} as core::ops::Fn<(&'a Foo,)>>::Output == _`:
 expected bound lifetime parameter 'a,
    found concrete lifetime [E0271]
<anon>:14     something(foo_as_bar);
              ^~~~~~~~~
<anon>:14:5: 14:14 note: required by `something`
<anon>:14     something(foo_as_bar);
              ^~~~~~~~~

cc @reem This is from the code I showed to you on IRC.

@steveklabnik steveklabnik added the A-typesystem Area: The type system label Feb 25, 2015
@theemathas
Copy link
Author

Changing the lifetime names to ease understanding

use std::marker::PhantomFn;

struct Foo(Bar);
struct Bar;

trait BorrowFn<'a>: PhantomFn<&'a Self, ()> {}
impl<'b, T: 'b, F: Fn(&'b Foo) -> T> BorrowFn<'b> for F {}

fn something<F>(_: F) where for<'c> F: BorrowFn<'c> {}

fn foo_as_bar<'d>(x: &'d Foo) -> &'d Bar { &x.0 }

fn main() {
    something(foo_as_bar);
}

playpen

The errors:

<anon>:14:5: 14:14 error: the requirement `for<'c> _ : 'c` is not satisfied [E0280]
<anon>:14     something(foo_as_bar);
              ^~~~~~~~~
<anon>:14:5: 14:14 error: type mismatch resolving `for<'c> <fn(&'d Foo) -> &'d Bar {foo_as_bar} as core::ops::Fn<(&'c Foo,)>>::Output == _`:
 expected bound lifetime parameter 'c,
    found concrete lifetime [E0271]
<anon>:14     something(foo_as_bar);
              ^~~~~~~~~
<anon>:14:5: 14:14 note: required by `something`
<anon>:14     something(foo_as_bar);
              ^~~~~~~~~

Note that for<'c> <fn(&'d Foo) -> ... as ...> doesn't really make sense. I don't think that 'd should appear there.

@Aatch
Copy link
Contributor

Aatch commented Feb 27, 2015

The 'd lifetimes are from foo_as_bar.

@theemathas theemathas changed the title Strange compile error with HRTB and Fn Generic fn cannot be converted to for<'a> Fn Feb 27, 2015
@theemathas
Copy link
Author

Possibly related to #22340

@apasel422
Copy link
Contributor

This is still an issue after removing the outdated PhantomFn bounds.

@steveklabnik
Copy link
Member

@apasel422 do you remember how to do so? getting a compileable example in this ticket would be helpful

@apasel422
Copy link
Contributor

@steveklabnik

I think the current version of this code is:

struct Foo(Bar);
struct Bar;

trait BorrowFn<'a> {}
impl<'b, T: 'b, F: Fn(&'b Foo) -> T> BorrowFn<'b> for F {}

fn something<F>(_: F) where for<'c> F: BorrowFn<'c> {}

fn foo_as_bar<'d>(x: &'d Foo) -> &'d Bar { &x.0 }

fn main() {
    something(foo_as_bar);
}

@Mark-Simulacrum
Copy link
Member

Closing in favor of #41078.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-typesystem Area: The type system
Projects
None yet
Development

No branches or pull requests

5 participants