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

non-defining existential type use in defining scope with empty lifetime name #53457

Closed
Nemo157 opened this issue Aug 17, 2018 · 9 comments
Closed

Comments

@Nemo157
Copy link
Member

@Nemo157 Nemo157 commented Aug 17, 2018

Really not sure where the error here is coming from, as far as I can tell there should only be a single relevant lifetime, 'a. The same function written as a free function generic over a Write returning impl Future<...> + 'a works fine (included in the playground). I'll try and come up with a reduced example in the next couple of days (playground)

error: non-defining existential type use in defining scope
  --> src/lib.rs:19:5
   |
19 | /     {
20 | |         poll_fn(move |cx| self.reborrow().poll_close(cx))
21 | |     }
   | |_____^ lifetime `` is part of concrete type but not used in parameter list of existential type
#![feature(arbitrary_self_types, existential_type, pin, futures_api)]

use std::future::Future;
use std::marker::Unpin;
use std::mem::PinMut;
use std::task::{self, Poll};

pub trait Write {
    type Error;

    fn poll_close(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Result<(), Self::Error>>;
}

existential type Close<'a, W: Write>: Future<Output = Result<(), W::Error>> + 'a;

trait WriteExt: Write {
    fn close<'a>(self: PinMut<'a, Self>) -> Close<'a, Self>
    where
        Self: Sized,
    {
        poll_fn(move |cx| self.reborrow().poll_close(cx))
    }
}

// ------------
// from futures-util-preview 0.3

pub struct PollFn<F> {
    f: F,
}

impl<F> Unpin for PollFn<F> {}

pub fn poll_fn<T, F>(f: F) -> PollFn<F>
where
    F: FnMut(&mut task::Context) -> Poll<T>,
{
    PollFn { f }
}

impl<T, F> Future for PollFn<F>
where
    F: FnMut(&mut task::Context) -> Poll<T>,
{
    type Output = T;

    fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<T> {
        (&mut self.f)(cx)
    }
}

(CC @oli-obk in case you have any hints on where to look)

@Nemo157
Copy link
Member Author

@Nemo157 Nemo157 commented Aug 20, 2018

Minimized example (playground)

#![feature(existential_type)]

trait Future {
    fn poll(&self, cx: &mut ());
}

trait Write {
    fn poll_close(&self, cx: &mut ());
}

existential type Close<'a, W: Write>: Future + 'a;

fn broken<'a, W: Write>(w: &'a W) -> Close<'a, W> {
    PollFn(move |cx| w.poll_close(cx))
}

fn working<'a, W: Write>(w: &'a W) -> impl Future + 'a {
    PollFn(move |cx| w.poll_close(cx))
}

pub struct PollFn<F: Fn(&mut ())>(F);

impl<F> Future for PollFn<F> where F: Fn(&mut ()) {
    fn poll(&self, cx: &mut ()) {
        (&self.0)(cx)
    }
}
error: non-defining existential type use in defining scope
  --> src/lib.rs:13:51
   |
13 |   fn broken<'a, W: Write>(w: &'a W) -> Close<'a, W> {
   |  ___________________________________________________^
14 | |     PollFn(move |cx| w.poll_close(cx))
15 | | }
   | |_^ lifetime `` is part of concrete type but not used in parameter list of existential type

Removing the cx parameter everywhere makes this work, at a guess it seems like existential types are incorrectly attributing the lifetime of the &mut () that should be hidden in the closure to the concrete type.

@oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Aug 21, 2018

This might be because existential types skip (

) the lifetime hacks (
for lifetime in &path.segments[0].args.as_ref().unwrap().args {
) that impl Trait does

@talchas
Copy link

@talchas talchas commented Oct 10, 2018

Even more minified:

existential type X: Clone;

fn bar<F: Fn(&i32) + Clone>(f: F) -> F {
    f
}

fn foo() -> X {
    bar(|x| ())
}

or using more stdlib stuff:

existential type X: Iterator<Item = i32>;

fn temp() -> X {
    vec![1].into_iter().filter(|x| *x > 1)
}
@ExpHP
Copy link
Contributor

@ExpHP ExpHP commented Oct 22, 2018

Also seen in const/static items of type impl Fn(&T): #55272

@matprec
Copy link
Contributor

@matprec matprec commented Jan 17, 2019

I've hit this as well, have reduced it further:

#![feature(existential_type)]

existential type Foo<R>: Fn(&R) -> ();

fn bar<R>() -> Foo<R> {
    |r| ()
}

Playground

Changing from Fn(&R) -> () to Fn(R) -> () works

@Lymia
Copy link
Contributor

@Lymia Lymia commented Mar 27, 2019

Has there been progress in fixing this? I'd be willing to see if I can start work on a PR myself since I've been having issues with this.

@oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Mar 27, 2019

I think it should be enough to add a ReLateBound(_) arm to

ty::ReStatic => region,

@oberien
Copy link
Contributor

@oberien oberien commented May 19, 2019

This seems to have been fixed recently, as the example in #53457 (comment) didn't work on nightly 2019-04-11, but now works on the playpen (if you click the link in that comment).

@oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Jun 3, 2019

The fix was in #60799

Centril added a commit to Centril/rust that referenced this issue Jun 4, 2019
Add regression test for existential type ICE rust-lang#53457

Closes rust-lang#53457.
bors added a commit that referenced this issue Jun 4, 2019
Rollup of 13 pull requests

Successful merges:

 - #61373 (Emit StorageDead along unwind paths for generators)
 - #61404 (miri unsizing: fix projecting into a field of an operand)
 - #61409 (Fix an ICE with a const argument in a trait)
 - #61413 (Re-implement async fn drop order lowering )
 - #61419 (Add an unusual-conversion example to to_uppercase)
 - #61420 (Succinctify splice docs)
 - #61444 (Suggest using `as_ref` on `*const T`)
 - #61446 (On TerminatorKind::DropAndReplace still handle unused_mut correctly)
 - #61485 (azure: retry s3 upload if it fails)
 - #61489 (ci: Reenable step timings on AppVeyor)
 - #61496 (Do not panic in tidy on unbalanced parentheses in cfg's)
 - #61497 (Treat 0 as special value for codegen-units-std)
 - #61499 (Add regression test for existential type ICE #53457)

Failed merges:

r? @ghost
Centril added a commit to Centril/rust that referenced this issue Jun 4, 2019
Add regression test for existential type ICE rust-lang#53457

Closes rust-lang#53457.
bors added a commit that referenced this issue Jun 4, 2019
Rollup of 14 pull requests

Successful merges:

 - #61135 (Fix documentation of `Rc::make_mut` regarding `rc::Weak`.)
 - #61404 (miri unsizing: fix projecting into a field of an operand)
 - #61409 (Fix an ICE with a const argument in a trait)
 - #61413 (Re-implement async fn drop order lowering )
 - #61419 (Add an unusual-conversion example to to_uppercase)
 - #61420 (Succinctify splice docs)
 - #61444 (Suggest using `as_ref` on `*const T`)
 - #61446 (On TerminatorKind::DropAndReplace still handle unused_mut correctly)
 - #61485 (azure: retry s3 upload if it fails)
 - #61489 (ci: Reenable step timings on AppVeyor)
 - #61494 (Utilize cfg(bootstrap) over cfg(stage0))
 - #61496 (Do not panic in tidy on unbalanced parentheses in cfg's)
 - #61497 (Treat 0 as special value for codegen-units-std)
 - #61499 (Add regression test for existential type ICE #53457)

Failed merges:

r? @ghost
Centril added a commit to Centril/rust that referenced this issue Jun 4, 2019
Add regression test for existential type ICE rust-lang#53457

Closes rust-lang#53457.
bors added a commit that referenced this issue Jun 4, 2019
Rollup of 13 pull requests

Successful merges:

 - #61135 (Fix documentation of `Rc::make_mut` regarding `rc::Weak`.)
 - #61404 (miri unsizing: fix projecting into a field of an operand)
 - #61409 (Fix an ICE with a const argument in a trait)
 - #61413 (Re-implement async fn drop order lowering )
 - #61419 (Add an unusual-conversion example to to_uppercase)
 - #61420 (Succinctify splice docs)
 - #61444 (Suggest using `as_ref` on `*const T`)
 - #61446 (On TerminatorKind::DropAndReplace still handle unused_mut correctly)
 - #61485 (azure: retry s3 upload if it fails)
 - #61489 (ci: Reenable step timings on AppVeyor)
 - #61496 (Do not panic in tidy on unbalanced parentheses in cfg's)
 - #61497 (Treat 0 as special value for codegen-units-std)
 - #61499 (Add regression test for existential type ICE #53457)

Failed merges:

r? @ghost
@bors bors closed this in #61499 Jun 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

7 participants